现在回答我的问题。
这是一个奇怪的错误,允许我使用 Object API 写入文件,因为显然 Object API 并不是要保存任何数据,而只是将其保留为 Object。Streaming API 的目的是保存或发送到流,但根本不保存。如果我们需要做任何一个或两个选项,这两种选择都很好也很方便。
在遇到这个问题后,我决定切换回 Streaming API 并且它可以工作,所以我想分享我对 Streaming API 和 Object API 的答案,因为它们都有不同的编码方式。
使用方法链的流式 API
private static void buildJsonUsingStreamingApi() {
//Create a StringWriter instance to buffer the JSON data.
StringWriter writer = new StringWriter();
//Create a JSON generator backed by the StringWriter instance created above.
JsonGenerator generator = Json.createGenerator(writer);
//Start building the JSON Data- Uses Method chaining technique.
//The JSON data gets streamed in the buffer as and when the
//different methods are invoked.
generator.writeStartArray()
.writeStartObject()//Indicates the start of an JSON object
.write("parentid", 23424900)
.write("name","Mexico City")
.write("url", "http://where.yahooapis.com/v1/place/116545")
.writeStartObject("placeType")//Creating a nested object i.e an JSON object withing another object
.write("name","Town")
.write("code", 7)
.writeEnd()
.write("woeid", 116545)
.writeEnd()//Indicates the end of an JSON object
.writeStartObject()
.write("name","Jackson")
.write("url", "http://where.yahooapis.com/v1/place/2428184")
.writeStartObject("placeType")
.write("name","Town")
.write("code", 7)
.writeEnd()
.write("parentid", 23424977)
.write("woeid", 2428184)
.writeEnd()
.writeEnd();//Indicates the end of the JSON array.
//Writes the data in the buffer to the String buffer.
generator.flush();
//Prints the JSON data onto the console.
System.out.println(writer.toString());
}
输出:
[
{
"parentid": 23424900,
"name": "Mexico City",
"url": "http://where.yahooapis.com/v1/place/116545",
"placeType": {
"name": "Town",
"code": 7
},
"woeid": 116545
},
{
"name": "Jackson",
"url": "http://where.yahooapis.com/v1/place/2428184",
"placeType": {
"name": "Town",
"code": 7
},
"parentid": 23424977,
"woeid": 2428184
}
]
现在你可以看到直接的方法,但我不能用我的应用程序做到这一点,所以这就是我完成它的方式。
没有方法链的流式 API
FileWriter fw = new FileWriter("c:\\example.txt");
JsonGenerator gen = Json.createGenerator(fw);
JsonGenerator mainObj = gen.writeStartObject(); //create your start object from the generator
mainObj.write("object1", 10); //write value:key pairs as needed
mainObj.write("object2", 1);
mainObj.write("object3", 11);
mainObj.write("object4", 11);
mainObj.write("object5", 12);
JsonGenerator loop1 = mainObj.writeStartArray("Loop1"); //When needing to create a new
//Array create a new start array
for(int i = 0; i < 2; i++) //based on the parent Object/Array, in this case "mainObj."
loop1.write(5); //could method chain
loop1.writeEnd(); //in this case I did not need to create a new
//object for each as I have only one element.
JsonGenerator loop2 = mainObj.writeStartArray("Loop2"); //same as above to create Array.
JsonGenerator loopObj2; //create new object
for(int i = 0; i < 9; i++)
{
loopObj2 = loop2.writeStartObject(); //using method-chaining with inner object
.write("LoopItem1",10) //creates an object each time from loop2.
.write("LoopItem2",12).writeEnd(); //note method-chaining doesn't have to be
//used here
/*loop2.writeStartObject() //If we switched to using this code we
.write("LoopItem1",10) //would be stuck with method-chaining.
.write("LoopItem2",12).writeEnd();*/ //loopObj2 isn't needed technically.
}
loop2.writeEnd();
JsonGenerator loop3 = mainObj.writeStartArray("Loop3"); //same as above
JsonGenerator loopObj3; //same as above
for(int i = 0; i < 3; i++)
{
loopObj3 = loop3.writeStartObject(); //create new object from loop3.
//note this is exactly the same as above, we
//just don't use method chaining here, even
//though we could chain the first 3
loopObj3.write("LoopItem1", 57);
loopObj3.write("LoopItem2", 67);
loopObj3.write("LoopItem3", 0);
System.out.println("Breaking Method-Chain just to do it...");
loopObj3.write("LoopItem4", 9);
loopObj3.writeEnd();
}
loop3.writeEnd();
mainObj.writeEnd();
gen.close();
输出:
{
"object1":10,
"object2":1,
"object3":11,
"object4":11,
"object5":12,
"Loop1":[
5,
12,
5,
12
],
"Loop2":[
{
"LoopItem1":10,
"LoopItem2":12
},
{
"LoopItem1":10,
"LoopItem2":12
},
{
"LoopItem1":10,
"LoopItem2":12
},
{
"LoopItem1":10,
"LoopItem2":12
},
{
"LoopItem1":10,
"LoopItem2":12
},
{
"LoopItem1":10,
"LoopItem2":12
},
{
"LoopItem1":10,
"LoopItem2":12
},
{
"LoopItem1":10,
"LoopItem2":12
},
{
"LoopItem1":10,
"LoopItem2":12
}
],
"Loop3":[
{
"LoopItem1":57,
"LoopItem2":67,
"LoopItem3":0,
"LoopItem4":9
},
{
"LoopItem1":57,
"LoopItem2":67,
"LoopItem3":0,
"LoopItem4":9
},
{
"LoopItem1":57,
"LoopItem2":67,
"LoopItem3":0,
"LoopItem4":9
}
]
}
我还想展示如何使用方法链接和调用来执行循环 3。
loopObj3.write("LoopItem1", 57)
.write("LoopItem2", 67)
.write("LoopItem3", 0);
System.out.println("Breaking Method-Chain just to do it...");
loopObj3.write("LoopItem4", 9);
loopObj3.writeEnd();
具有方法链的对象 API
private static void buildJsonUsingObjectModelApi() {
System.out.println("Json Building using Object Model API");
JsonArray jsonArray =
//Create an Array Builder to build an JSON Array
Json.createArrayBuilder()
.add(Json.createObjectBuilder()//Create an Object builder to build JSON Object
.add("parentid", 23424900)
.add("name","Jackson")
.add("url", "http://where.yahooapis.com/v1/place/2428184")
.add("placeType", Json.createObjectBuilder()//Another nested JSON Object
.add("name", "Town")
.add("code",7)
)
.add("woeid", 116545)
.build()//The JSON Object completely constructed.
)
.add(Json.createObjectBuilder()//Another object builder to build JSON Object.
.add("name","Mexico City")
.add("url", "http://where.yahooapis.com/v1/place/116545")
.add("placeType", Json.createObjectBuilder()
.add("name", "Town")
.add("code",7)
)
.add("parentid", 23424977)
.add("woeid", 2428184)
.build()
)
.build();
StringWriter writer = new StringWriter();
//Extracting the JSON data from the JSON object tree into the string.
Json.createWriter(writer).writeArray(jsonArray);
System.out.println(writer.toString());
}
输出:
[
{
"parentid":23424900,
"name":"Jackson",
"url":"http://where.yahooapis.com/v1/place/2428184",
"placeType":{
"name":"Town",
"code":7
},
"woeid":116545
},
{
"name":"Mexico City",
"url":"http://where.yahooapis.com/v1/place/116545",
"placeType":{
"name":"Town",
"code":7
},
"parentid":23424977,
"woeid":2428184
}
]
没有方法链的对象 API
JsonObjectBuilder mainObj = Json.createObjectBuilder();
mainObj.add("object1", 10);
mainObj.add("object2", 1);
mainObj.add("object3", 11);
mainObj.add("object4", 11);
mainObj.add("object5", 12);
JsonArrayBuilder loop1 = Json.createArrayBuilder();
for(int i = 0; i < 2; i++)
loop1.add(i);
mainObj.add("Loop1", loop1);
JsonArrayBuilder loop2 = Json.createArrayBuilder();
for(int i = 0; i < 9; i++)
{
loop2.add(Json.createObjectBuilder()
.add("LoopItem1",10)
.add("LoopItem2",12));
}
mainObj.add("Loop2",loop2);
JsonArrayBuilder loop3 = Json.createArrayBuilder();
JsonObjectBuilder loop3Obj;
for(int i = 0; i < 3; i++)
{
loop3Obj = Json.createObjectBuilder()
.add("LoopItem1", 57)
.add("LoopItem2", 67)
.add("LoopItem3", 0);
System.out.println("Breaking Method-Chain just to do it...");
loop3Obj.add("LoopItem4", 9);
loop3.add(loop3Obj);
}
mainObj.add("Loop3", loop3);
JsonObject planObj = mainObj.build();
StringWriter writer = new StringWriter();
JsonWriter jwrite = Json.createWriter(writer);
jwrite.write(planObj);
System.out.println(planObj.toString());
输出:
{
"object1":10,
"object2":1,
"object3":11,
"object4":11,
"object5":12,
"Loop1":[
0,
1
],
"Loop2":[
{
"LoopItem1":10,
"LoopItem2":12
},
{
"LoopItem1":10,
"LoopItem2":12
},
{
"LoopItem1":10,
"LoopItem2":12
},
{
"LoopItem1":10,
"LoopItem2":12
},
{
"LoopItem1":10,
"LoopItem2":12
},
{
"LoopItem1":10,
"LoopItem2":12
},
{
"LoopItem1":10,
"LoopItem2":12
},
{
"LoopItem1":10,
"LoopItem2":12
},
{
"LoopItem1":10,
"LoopItem2":12
}
],
"Loop3":[
{
"LoopItem1":57,
"LoopItem2":67,
"LoopItem3":0,
"LoopItem4":9
},
{
"LoopItem1":57,
"LoopItem2":67,
"LoopItem3":0,
"LoopItem4":9
},
{
"LoopItem1":57,
"LoopItem2":67,
"LoopItem3":0,
"LoopItem4":9
}
]
}
前 3 个被链接,然后我有我的阻塞器,它只是 println,然后我写另一个项目,然后 writeEnd() 和单独的方法调用。
现在你们中的一些人可能会抱怨“但你确实在你的一个内部对象中使用了方法链接!!!” 是的,是的,但正如我所提到的,我不必这样做,我想解释一下,无论有没有它,我都可以做到这一点,甚至可以同时使用两者来显示灵活性。
我希望这对其他人有所帮助。这花了我几天时间来学习和理解 API,所以我想分享我的发现。我也花了大约 3-4 个小时来写这个教程,所以我希望它确实有用,人们喜欢它。
谢谢大家:)。