我想通过使用新的 JSR-353 来分享我的问题/答案,它是用于 JSON 处理的 Java API。具体来说,您可以在 2 个不同的“API”(流式 API 和对象 API)中操作 JSON 数据。
如果你在 google 中输入“jsr-353 tutorial”,你会得到很多结果。
https://jcp.org/en/jsr/detail?id=353 ~ 具体要求的详细信息。
https://jsonp.java.net/ ~ API 的主要站点,还链接到位于此处“文档”下的 Oracle 教程 https://docs.oracle.com/javaee/7/tutorial/doc/jsonp.htm稍后我将详细讨论本教程。
最后是这个
http://www.javabeat.net/java-json-api-jsr-353/
我想先谈谈最后一个链接,因为它为我的入门提供了很多很好的细节,并且是仅有的真正教程之一(还有其他教程,但它们基本相同)。
我真正尝试了解 API 从新到不仅是这个 API,而且一般是 JSON。
如果您希望将 JSON 数据写入字符流(如文件)或字节流,那么 Streaming API 将是最佳选择,因为它直接执行写入缓冲区的操作无需在内存中构建对象树,即在创建最终 JSON 数据之前不会生成中间形式。
如果您想将 JSON 数据作为对象树保存在内存中,即不写入任何流,而是将树存储在内存中,以便可以重用 JSON 数据而无需重新解析它或一个也可以序列化对象树以持久化/保存 JSON 数据。这里的 JSON 数据将以对象树的形式表示。
现在 Streaming API 的描述对我来说很有意义,我需要保存一个文件,所以这对我来说很有意义。
至于对象 API,它所做的事情也很有意义,保存对象以便我以后可以在我的代码中重用它,太棒了。
问题是我没有得到我的问题的答案,我将解释我现在正在寻找什么。
我基本上有 1 个包含其他对象/数组的对象。
最初我使用 BufferedWriter 将数据写入文本文件中的新行。
我的格式看起来像这样。
bw.write(1);
bw.newLine();
bw.write(2);
bw.newLine();
for(int i = 0; i < 4; i++)
{
bw.write(i);
bw.newLine();
}
bw.write(2);
bw.newLine();
for(int j = 0; j < 2; j++)
{
bw.write(j);
bw.newLine();
bw.write(j+5);
bw.newLine();
bw.write(2);
bw.newLine();
bw.write(j*4);
bw.newLine();
}
bw.write(12);
bw.newLine();
for(int k = 0; k < 82; k++)
{
bw.write(k);
bw.newLine();
bw.write(k*5);
bw.newLine();
//do some additional code here
bw.write(2);
bw.newLine();
bw.write(k*4);
bw.newLine();
}
然后结束。授予数字等占位符,实际上从写入数据到循环量的所有内容都是我从另一个文件读取的可变数据。
如您所见,我无法使用 JSR-353 附带的传统“方法链”。
至于什么是方法链,看看wiki http://en.wikipedia.org/wiki/Method_chaining .一个使用 Streaming API 的方法链接的例子是这样的,如上面的教程所示:
FileWriter writer = new FileWriter("c:\\example.txt");
JsonGenerator gen = Json.createGenerator(writer);
gen.writeStartObject()
.write("firstName", "Duke")
.write("lastName", "Java")
.write("age", 18)
.write("street/Address", "100 Internet Dr")
.write("city", "JavaTown")
.write("state", "JA")
.write("postalCode", "12345")
.writeStartArray("phoneNumbers")
.writeStartObject()
.write("type", "mobile")
.write("number", "111-111-1111")
.writeEnd()
.writeStartObject()
.write("type", "home")
.write("number", "222-222-2222")
.writeEnd()
.writeEnd()
.writeEnd();
gen.close();
我还查看了 Oracle 教程,当我在寻找一种保存文件的方法时,我在看到“生成/解析”的地方有点困惑。
https://docs.oracle.com/javaee/7/tutorial/doc/jsonp001.htm
19.1.3 Generating and Parsing JSON Data
For generating and parsing JSON data, there are two programming models, which are similar to those used for XML documents.
The streaming model uses an event-based parser that reads JSON data one element at a time. The parser generates events and stops for processing when an object or an array begins or ends, when it finds a key, or when it finds a value. Each element can be processed or discarded by the application code, and then the parser proceeds to the next event. This approach is adequate for local processing, in which the processing of an element does not require information from the rest of the data. The streaming model generates JSON output to a given stream by making a function call with one element at a time.
教程提到了这一点,但它的确切含义令人困惑,尤其是我认为这是为了写作而不是阅读。当它提到最后一行(粗体)时,它为什么一次只做一个并没有多大意义,并且看起来它只处理对象的一部分,而不是整个对象,正如 Object API 提到的那样处理整棵树。
因此,我没有处理 Streaming API,而是从 Object API 开始。我首先尝试将文件保存到 FileWriter,但什么也不会保存。最终我切换到 StringWriter 并在我的项目中使用它。我决定在完成我的结构并以某种方式将其保存到文件后切换回 FileWriter,但我意识到我的部分代码最后被切断了。我试着做一个微小的结构,但它什么也打印不出来。
最佳答案
是一些奇怪的错误允许我使用对象 API 写入文件,因为显然对象 API 并不意味着保存任何数据,而只是将其作为对象保存。 Streaming API 的目的是保存或发送到流,但根本不保存。如果我们需要做 or ,那么同时拥有这两个选项既好又方便。
在遇到这个问题后,我决定切换回 Streaming API 并且它可以工作,所以我想分享我对 Streaming API 和 Object 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
}
]
现在你可以看到直接的方法,但我不能用我的应用程序做到这一点,所以这就是我完成它的方法。
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();
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
}
]
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() 与单独的方法调用。
现在你们中的一些人可能会提示“但是你们确实在你们的一个内部对象中使用了方法链接!!!”是的,是的,我这样做了,但正如我提到的,我不必这样做,我想解释一下,无论有没有它,我都可以做到这一点,甚至可以同时使用两者以显示灵 active 。
我希望这对其他人有所帮助。我花了几天时间来学习和理解 API,所以我想分享我的发现。我也花了大约 3-4 个小时来编写本教程,所以我希望它能得到一些用处,并且人们会喜欢它。
谢谢大家:)。
关于java - 如何在没有方法链接的情况下使用 "JSR-353: Java API for JSON Processing,",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26833439/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-