如何在Java中解析JSON

我有以下JSON文本。如何解析它以获取pageNamepagePicpost_id等的值?

{"pageInfo": {"pageName": "abc","pagePic": "http://example.com/content.jpg"},"posts": [{"post_id": "123456789012_123456789012","actor_id": "1234567890","picOfPersonWhoPosted": "http://example.com/photo.jpg","nameOfPersonWhoPosted": "Jane Doe","message": "Sounds cool. Can't wait to see it!","likesCount": "2","comments": [],"timeOfPost": "1234567890"}]}
2269342 次浏览

快速json解析器非常简单、灵活、非常快速且可定制。试试看

产品特点:

  • 符合JSON规范(RFC4627)
  • 高性能JSON解析器
  • 支持灵活/可配置的解析方法
  • 任何JSON层次结构的键/值对的可配置验证
  • 易于使用#占地面积很小
  • 提高开发人员友好和易于跟踪异常
  • 可插拔的自定义验证支持-键/值可以在遇到时通过配置自定义验证器来验证
  • 验证和非验证解析器支持
  • 支持两种类型的配置(JSON/XML),以使用快速JSON验证解析器
  • 需要JDK 1.5
  • 不依赖外部库
  • 通过对象序列化支持JSON生成
  • 支持解析过程中的集合类型选择

它可以像这样使用:

JsonParserFactory factory=JsonParserFactory.getInstance();JSONParser parser=factory.newJsonParser();Map jsonMap=parser.parseJson(jsonString);

我相信最好的做法应该是通过官方的JavaJSON API,这仍然是半成品。

org.json库易于使用。

请记住(在铸造或使用getJSONObjectgetJSONArray等方法时)在JSON表示法中

  • [ … ]表示一个数组,因此库将其解析为JSONArray
  • { … }表示一个对象,因此库将其解析为JSONObject

下面的示例代码:

import org.json.*;
String jsonString = ... ; //assign your JSON String hereJSONObject obj = new JSONObject(jsonString);String pageName = obj.getJSONObject("pageInfo").getString("pageName");
JSONArray arr = obj.getJSONArray("posts"); // notice that `"posts": [...]`for (int i = 0; i < arr.length(); i++){String post_id = arr.getJSONObject(i).getString("post_id");......}

您可以从以下位置找到更多示例:在Java中解析JSON

可下载的jar:http://mvnrepository.com/artifact/org.json/json

这让我大吃一惊,因为它是多么容易。您可以将包含JSON的String传递给默认org.json包中JSONObject的构造函数。

JSONArray rootOfPage =  new JSONArray(JSONString);

完成。放下麦克风。这也适用于JSONObjects。之后,您可以使用对象上的get()方法查看Objects的层次结构。

  1. 如果想从JSON创建Java对象,反之亦然,请使用GSON或JACKSON第三方jar等。

    //from object to JSONGson gson = new Gson();gson.toJson(yourObject);
    // from JSON to objectyourObject o = gson.fromJson(JSONString,yourObject.class);
  2. But if one just want to parse a JSON string and get some values, (OR create a JSON string from scratch to send over wire) just use JaveEE jar which contains JsonReader, JsonArray, JsonObject etc. You may want to download the implementation of that spec like javax.json. With these two jars I am able to parse the json and use the values.

    These APIs actually follow the DOM/SAX parsing model of XML.

    Response response = request.get(); // REST callJsonReader jsonReader = Json.createReader(new StringReader(response.readEntity(String.class)));JsonArray jsonArray = jsonReader.readArray();ListIterator l = jsonArray.listIterator();while ( l.hasNext() ) {JsonObject j = (JsonObject)l.next();JsonObject ciAttr = j.getJsonObject("ciAttributes");

请做这样的事情:

JSONParser jsonParser = new JSONParser();JSONObject obj = (JSONObject) jsonParser.parse(contentString);String product = (String) jsonObject.get("productId");
{"pageInfo": {"pageName": "abc","pagePic": "http://example.com/content.jpg"},"posts": [{"post_id": "123456789012_123456789012","actor_id": "1234567890","picOfPersonWhoPosted": "http://example.com/photo.jpg","nameOfPersonWhoPosted": "Jane Doe","message": "Sounds cool. Can't wait to see it!","likesCount": "2","comments": [],"timeOfPost": "1234567890"}]}
Java code :
JSONObject obj = new JSONObject(responsejsonobj);String pageName = obj.getJSONObject("pageInfo").getString("pageName");
JSONArray arr = obj.getJSONArray("posts");for (int i = 0; i < arr.length(); i++){String post_id = arr.getJSONObject(i).getString("post_id");......etc}

为了示例的缘故,让我们假设您有一个只有name的类#0

private class Person {public String name;
public Person(String name) {this.name = name;}}

谷歌GSONMaven

我个人最喜欢的是对象的JSON序列化/反序列化。

Gson g = new Gson();
Person person = g.fromJson("{\"name\": \"John\"}", Person.class);System.out.println(person.name); //John
System.out.println(g.toJson(person)); // {"name":"John"}

更新

如果您想获取单个属性,您也可以使用Google库轻松完成:

JsonObject jsonObject = new JsonParser().parse("{\"name\": \"John\"}").getAsJsonObject();
System.out.println(jsonObject.get("name").getAsString()); //John

Org.JSONMaven

如果您不需要对象反序列化,而是简单地获取一个属性,您可以尝试org.json(或者看看上面的GSON示例!

JSONObject obj = new JSONObject("{\"name\": \"John\"}");
System.out.println(obj.getString("name")); //John

杰克逊Maven

ObjectMapper mapper = new ObjectMapper();Person user = mapper.readValue("{\"name\": \"John\"}", Person.class);
System.out.println(user.name); //John

如果你有一些Java类(比如Message)表示JSON字符串(jsonString),你可以使用杰克逊 JSON库:

Message message= new ObjectMapper().readValue(jsonString, Message.class);

从消息对象中,您可以获取它的任何属性。

几乎所有给出的答案都需要在访问感兴趣属性中的值之前将JSON完全反序列化为Java对象。另一种不遵循此路线的替代方案是使用JsonPATH,它类似于JSON的XPath,并允许遍历JSON对象。

这是一个规范,JayWay的优秀人员已经为规范创建了一个Java实现,您可以在这里找到:https://github.com/jayway/JsonPath

所以基本上要使用它,将其添加到您的项目中,例如:

<dependency><groupId>com.jayway.jsonpath</groupId><artifactId>json-path</artifactId><version>${version}</version></dependency>

并使用:

String pageName = JsonPath.read(yourJsonString, "$.pageInfo.pageName");String pagePic = JsonPath.read(yourJsonString, "$.pageInfo.pagePic");String post_id = JsonPath.read(yourJsonString, "$.pagePosts[0].post_id");

等…

查看JsonPath规范页面,了解有关横向JSON的其他方法的更多信息。

除了其他答案,我推荐这个在线开源服务jsonschema2pojo.org,用于从GSON、Jackson 1. x或Jackson 2. x的json或json模式快速生成Java类。例如,如果您有:

{"pageInfo": {"pageName": "abc","pagePic": "http://example.com/content.jpg"}"posts": [{"post_id": "123456789012_123456789012","actor_id": 1234567890,"picOfPersonWhoPosted": "http://example.com/photo.jpg","nameOfPersonWhoPosted": "Jane Doe","message": "Sounds cool. Can't wait to see it!","likesCount": 2,"comments": [],"timeOfPost": 1234567890}]}

生成的GSON的jsonschema2pojo.org

@Generated("org.jsonschema2pojo")public class Container {@SerializedName("pageInfo")@Exposepublic PageInfo pageInfo;@SerializedName("posts")@Exposepublic List<Post> posts = new ArrayList<Post>();}
@Generated("org.jsonschema2pojo")public class PageInfo {@SerializedName("pageName")@Exposepublic String pageName;@SerializedName("pagePic")@Exposepublic String pagePic;}
@Generated("org.jsonschema2pojo")public class Post {@SerializedName("post_id")@Exposepublic String postId;@SerializedName("actor_id")@Exposepublic long actorId;@SerializedName("picOfPersonWhoPosted")@Exposepublic String picOfPersonWhoPosted;@SerializedName("nameOfPersonWhoPosted")@Exposepublic String nameOfPersonWhoPosted;@SerializedName("message")@Exposepublic String message;@SerializedName("likesCount")@Exposepublic long likesCount;@SerializedName("comments")@Exposepublic List<Object> comments = new ArrayList<Object>();@SerializedName("timeOfPost")@Exposepublic long timeOfPost;}

Gson很容易学习和实现,我们需要知道的是以下两个方法

  • toJson()-将Java对象转换为JSON格式

  • from mJson()-将JSON转换为Java对象

'

import java.io.BufferedReader;import java.io.FileReader;import java.io.IOException;import com.google.gson.Gson;
public class GsonExample {public static void main(String[] args) {
Gson gson = new Gson();
try {
BufferedReader br = new BufferedReader(new FileReader("c:\\file.json"));
//convert the json string back to objectDataObject obj = gson.fromJson(br, DataObject.class);
System.out.println(obj);
} catch (IOException e) {e.printStackTrace();}
}}

'

阅读以下博客文章,JSONJava

这篇文章有点老了,但我还是想回答你的问题。

步骤1:创建数据的POJO类。

第2步:现在使用JSON创建一个对象。

Employee employee = null;ObjectMapper mapper = new ObjectMapper();try {employee =  mapper.readValue(newFile("/home/sumit/employee.json"), Employee.class);}catch(JsonGenerationException e) {e.printStackTrace();}

如需进一步参考,您可以参考以下链接

下面的示例显示了如何读取问题中的文本,表示为“jsonText”变量。此解决方案使用JavaEE7javax.json API(在其他一些答案中提到)。我将其作为单独答案添加的原因是,以下代码显示了如何实际上访问问题中显示的一些值。运行此代码需要实现javax.jsonAPI。由于我不想声明“导入”语句,因此包含了每个所需类的完整包。

javax.json.JsonReader jr =javax.json.Json.createReader(new StringReader(jsonText));javax.json.JsonObject jo = jr.readObject();
//Read the page info.javax.json.JsonObject pageInfo = jo.getJsonObject("pageInfo");System.out.println(pageInfo.getString("pageName"));
//Read the posts.javax.json.JsonArray posts = jo.getJsonArray("posts");//Read the first post.javax.json.JsonObject post = posts.getJsonObject(0);//Read the post_id field.String postId = post.getString("post_id");

现在,在任何人因为它不使用GSON、org.json、Jackson或任何其他可用的第三方框架而否决这个答案之前,它是每个问题解析提供文本的“必需代码”的示例。我很清楚JDK 9不考虑遵守当前标准JSR 353JSR 353规范应该被视为与任何其他第三方JSON处理实现相同。

您可以使用googlegson

使用这个库,您只需要创建一个具有相同JSON结构的模型。然后模型会自动填充。您必须调用您的变量作为您的JSON键,或者如果您想使用不同的名称,请使用#0

JSON

从你的例子:

{"pageInfo": {"pageName": "abc","pagePic": "http://example.com/content.jpg"}"posts": [{"post_id": "123456789012_123456789012","actor_id": "1234567890","picOfPersonWhoPosted": "http://example.com/photo.jpg","nameOfPersonWhoPosted": "Jane Doe","message": "Sounds cool. Can't wait to see it!","likesCount": "2","comments": [],"timeOfPost": "1234567890"}]}

模型

class MyModel {
private PageInfo pageInfo;private ArrayList<Post> posts = new ArrayList<>();}
class PageInfo {
private String pageName;private String pagePic;}
class Post {
private String post_id;
@SerializedName("actor_id") // <- example SerializedNameprivate String actorId;
private String picOfPersonWhoPosted;private String nameOfPersonWhoPosted;private String message;private String likesCount;private ArrayList<String> comments;private String timeOfPost;}

解析

现在您可以使用Gson库进行解析:

MyModel model = gson.fromJson(jsonString, MyModel.class);

Gradle导入

记得在app Gradle文件中导入库

implementation 'com.google.code.gson:gson:2.8.6' // or earlier versions

模型自动生成

您可以使用这个等在线工具自动从JSON生成模型。

Java中有许多可用的JSON库。

最臭名昭著的是:Jackson、GSON、Genson、FastJson和org.json.

在选择任何库时,通常应该考虑三件事:

  1. 性能
  2. 易用性(代码易于编写且清晰易读)-这与功能相匹配。
  3. 对于移动应用程序:依赖项/jar大小

特别是对于JSON库(以及任何序列化/反序列化库),数据绑定通常也很有趣,因为它消除了编写样板代码来打包/解包数据的需要。

对于1,请参阅此基准:https://github.com/fabienrenaud/java-json-benchmark我使用JMH比较(jackson, gson, genson,org.json, jsonp)使用流和数据库API的序列化器和反序列化器的性能。对于2,您可以在Internet上找到许多示例。上面的基准测试也可以用作示例的来源…

快速了解基准:杰克逊的性能比org.json好5到6倍,比GSON好两倍多。

对于您的特定示例,以下代码使用jackson解码您的json:

public class MyObj {
private PageInfo pageInfo;private List<Post> posts;
static final class PageInfo {private String pageName;private String pagePic;}
static final class Post {private String post_id;@JsonProperty("actor_id");private String actorId;@JsonProperty("picOfPersonWhoPosted")private String pictureOfPoster;@JsonProperty("nameOfPersonWhoPosted")private String nameOfPoster;private String likesCount;private List<String> comments;private String timeOfPost;}
private static final ObjectMapper JACKSON = new ObjectMapper();public static void main(String[] args) throws IOException {MyObj o = JACKSON.readValue(args[0], MyObj.class); // assumes args[0] contains your json payload provided in your question.}}

让我知道如果你有任何问题。

A-解释

您可以使用杰克逊库将JSON String绑定到POJO普通旧Java对象)实例中。POJO只是一个只有私有字段和公共getter/setter方法的类。Jackson将遍历方法(使用反射),并将JSON对象映射到POJO实例,因为类的字段名适合JSON对象的字段名。

在您的JSON对象中,它实际上是一个复合对象,主对象由两个子对象组成。因此,我们的POJO类应该具有相同的层次结构。我将整个JSON对象称为对象。对象由页面信息对象和发布对象数组组成。

所以我们必须创建三个不同的POJO类;

  • 类,页面信息类和发布实例数组的组合
  • 页面信息
  • 员额

我使用的唯一包是Jackson ObjectMapper,我们所做的是绑定数据;

com.fasterxml.jackson.databind.ObjectMapper

所需的依赖项,下面列出了jar文件;

  • jackson-core-2.5.1.jar
  • jackson-databind-2.5.1.jar
  • jackson-annotations-2.5.0.jar

这是所需的代码;

B-主POJO类:页面

package com.levo.jsonex.model;
public class Page {    
private PageInfo pageInfo;private Post[] posts;
public PageInfo getPageInfo() {return pageInfo;}
public void setPageInfo(PageInfo pageInfo) {this.pageInfo = pageInfo;}
public Post[] getPosts() {return posts;}
public void setPosts(Post[] posts) {this.posts = posts;}    
}

C-儿童POJO课程:PageInfo

package com.levo.jsonex.model;
public class PageInfo {    
private String pageName;private String pagePic;    
public String getPageName() {return pageName;}    
public void setPageName(String pageName) {this.pageName = pageName;}    
public String getPagePic() {return pagePic;}    
public void setPagePic(String pagePic) {this.pagePic = pagePic;}    
}

D-儿童POJO班:职位

package com.levo.jsonex.model;
public class Post {    
private String post_id;private String actor_id;private String picOfPersonWhoPosted;private String nameOfPersonWhoPosted;private String message;private int likesCount;private String[] comments;private int timeOfPost;
public String getPost_id() {return post_id;}
public void setPost_id(String post_id) {this.post_id = post_id;}
public String getActor_id() {return actor_id;}
public void setActor_id(String actor_id) {this.actor_id = actor_id;}
public String getPicOfPersonWhoPosted() {return picOfPersonWhoPosted;}    
public void setPicOfPersonWhoPosted(String picOfPersonWhoPosted) {this.picOfPersonWhoPosted = picOfPersonWhoPosted;}
public String getNameOfPersonWhoPosted() {return nameOfPersonWhoPosted;}
public void setNameOfPersonWhoPosted(String nameOfPersonWhoPosted) {this.nameOfPersonWhoPosted = nameOfPersonWhoPosted;}
public String getMessage() {return message;}
public void setMessage(String message) {this.message = message;}
public int getLikesCount() {return likesCount;}
public void setLikesCount(int likesCount) {this.likesCount = likesCount;}
public String[] getComments() {return comments;}
public void setComments(String[] comments) {this.comments = comments;}
public int getTimeOfPost() {return timeOfPost;}
public void setTimeOfPost(int timeOfPost) {this.timeOfPost = timeOfPost;}    
}

示例JSON文件:sampleJSONFile.json

我刚刚将您的JSON示例复制到此文件中并将其放在项目文件夹下。

{"pageInfo": {"pageName": "abc","pagePic": "http://example.com/content.jpg"},"posts": [{"post_id": "123456789012_123456789012","actor_id": "1234567890","picOfPersonWhoPosted": "http://example.com/photo.jpg","nameOfPersonWhoPosted": "Jane Doe","message": "Sounds cool. Can't wait to see it!","likesCount": "2","comments": [],"timeOfPost": "1234567890"}]}

F-演示代码

package com.levo.jsonex;
import java.io.File;import java.io.IOException;import java.util.Arrays;
import com.fasterxml.jackson.databind.ObjectMapper;import com.levo.jsonex.model.Page;import com.levo.jsonex.model.PageInfo;import com.levo.jsonex.model.Post;
public class JSONDemo {    
public static void main(String[] args) {ObjectMapper objectMapper = new ObjectMapper();        
try {Page page = objectMapper.readValue(new File("sampleJSONFile.json"), Page.class);            
printParsedObject(page);} catch (IOException e) {e.printStackTrace();}        
}    
private static void printParsedObject(Page page) {printPageInfo(page.getPageInfo());System.out.println();printPosts(page.getPosts());}
private static void printPageInfo(PageInfo pageInfo) {System.out.println("Page Info;");System.out.println("**********");System.out.println("\tPage Name : " + pageInfo.getPageName());System.out.println("\tPage Pic  : " + pageInfo.getPagePic());}    
private static void printPosts(Post[] posts) {System.out.println("Page Posts;");System.out.println("**********");for(Post post : posts) {printPost(post);}}    
private static void printPost(Post post) {System.out.println("\tPost Id                   : " + post.getPost_id());System.out.println("\tActor Id                  : " + post.getActor_id());System.out.println("\tPic Of Person Who Posted  : " + post.getPicOfPersonWhoPosted());System.out.println("\tName Of Person Who Posted : " + post.getNameOfPersonWhoPosted());System.out.println("\tMessage                   : " + post.getMessage());System.out.println("\tLikes Count               : " + post.getLikesCount());System.out.println("\tComments                  : " + Arrays.toString(post.getComments()));System.out.println("\tTime Of Post              : " + post.getTimeOfPost());}    
}

G-演示输出

Page Info;****(*****Page Name : abcPage Pic  : http://example.com/content.jpgPage Posts;**********Post Id                   : 123456789012_123456789012Actor Id                  : 1234567890Pic Of Person Who Posted  : http://example.com/photo.jpgName Of Person Who Posted : Jane DoeMessage                   : Sounds cool. Can't wait to see it!Likes Count               : 2Comments                  : []Time Of Post              : 1234567890

此页面上的热门答案使用了过于简单的示例,例如具有一个属性的对象(例如{name: value})。我认为这个仍然简单但真实的例子可以帮助某人。

所以这是谷歌翻译API返回的JSON:

{"data":{"translations":[{"translatedText": "Arbeit"}]}}

我想使用Google的Gson检索“translatedText”属性的值,例如“Arbeit”。

两种可能的方法:

  1. 只检索一个需要的属性

     String json  = callToTranslateApi("work", "de");JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();return jsonObject.get("data").getAsJsonObject().get("translations").getAsJsonArray().get(0).getAsJsonObject().get("translatedText").getAsString();
  2. 从JSON创建Java对象

     class ApiResponse {Data data;class Data {Translation[] translations;class Translation {String translatedText;}}}

      Gson g = new Gson();String json =callToTranslateApi("work", "de");ApiResponse response = g.fromJson(json, ApiResponse.class);return response.data.translations[0].translatedText;

您可以使用jayway jsonPath。下面是一个包含源代码、pom详细信息和良好留档的GitHub链接。

https://github.com/jayway/JsonPath

请按照以下步骤操作。

步骤1:使用Maven在类路径中添加jayway JSON路径依赖项,或者下载JAR文件并手动添加它。

<dependency><groupId>com.jayway.jsonpath</groupId><artifactId>json-path</artifactId><version>2.2.0</version></dependency>

步骤2:请将您的输入JSON保存为此示例的文件。在我的情况下,我将您的JSON保存为sampleJson.txt.注意,您错过了pageInfo和帖子之间的逗号。

步骤3:使用bufferedReader从上述文件中读取JSON内容并将其保存为String。

BufferedReader br = new BufferedReader(new FileReader("D:\\sampleJson.txt"));
StringBuilder sb = new StringBuilder();String line = br.readLine();
while (line != null) {sb.append(line);sb.append(System.lineSeparator());line = br.readLine();}br.close();String jsonInput = sb.toString();

步骤4:使用jayway JSON解析器解析您的JSON字符串。

Object document = Configuration.defaultConfiguration().jsonProvider().parse(jsonInput);

步骤5:阅读下面的详细信息。

String pageName = JsonPath.read(document, "$.pageInfo.pageName");String pagePic = JsonPath.read(document, "$.pageInfo.pagePic");String post_id = JsonPath.read(document, "$.posts[0].post_id");
System.out.println("$.pageInfo.pageName " + pageName);System.out.println("$.pageInfo.pagePic " + pagePic);System.out.println("$.posts[0].post_id " + post_id);

输出将是

$.pageInfo.pageName = abc$.pageInfo.pagePic = http://example.com/content.jpg$.posts[0].post_id  = 123456789012_123456789012

使用最小化json,它非常快速且易于使用。您可以从String obj和Stream解析。

示例数据:

{"order": 4711,"items": [{"name": "NE555 Timer IC","cat-id": "645723","quantity": 10,},{"name": "LM358N OpAmp IC","cat-id": "764525","quantity": 2}]}

解析:

JsonObject object = Json.parse(input).asObject();int orders = object.get("order").asInt();JsonArray items = object.get("items").asArray();

创建JSON:

JsonObject user = Json.object().add("name", "Sakib").add("age", 23);

Maven:

<dependency><groupId>com.eclipsesource.minimal-json</groupId><artifactId>minimal-json</artifactId><version>0.9.4</version></dependency>

我有这样的JSON:

{"pageInfo": {"pageName": "abc","pagePic": "http://example.com/content.jpg"}}

Java课

class PageInfo {
private String pageName;private String pagePic;
// Getters and setters}

将此JSON转换为Java类的代码。

    PageInfo pageInfo = JsonPath.parse(jsonString).read("$.pageInfo", PageInfo.class);

Maven

<dependency><groupId>com.jayway.jsonpath</groupId><artifactId>json-path</artifactId><version>2.2.0</version></dependency>

首先,您需要选择一个实现库来执行此操作。

用于JSON处理的JavaAPI(JSR 353)提供了可移植的API,用于使用对象模型和流API解析、生成、转换和查询JSON。

参考实现在这里:https://jsonp.java.net/

在这里您可以找到JSR 353的实现列表

实现JSR-353(JSON)的API是什么?

来帮你决定我也找到了这篇文章:

http://blog.takipi.com/the-ultimate-json-library-json-simple-vs-gson-vs-jackson-vs-json/

如果你选择Jackson,这里有一篇关于使用Jackson在JSON和Java之间转换的好文章:https://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson/

希望有帮助!

由于还没有人提到它,这里是使用Nashorn(Java8的JavaScript运行时部分,但在Java11中已弃用)的解决方案的开始。

解决方案

private static final String EXTRACTOR_SCRIPT ="var fun = function(raw) { " +"var json = JSON.parse(raw); " +"return [json.pageInfo.pageName, json.pageInfo.pagePic, json.posts[0].post_id];};";
public void run() throws ScriptException, NoSuchMethodException {ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");engine.eval(EXTRACTOR_SCRIPT);Invocable invocable = (Invocable) engine;JSObject result = (JSObject) invocable.invokeFunction("fun", JSON);result.values().forEach(e -> System.out.println(e));}

性能对比

我编写了包含分别由20、20和100个元素组成的三个数组的JSON内容。我只想从第三个数组中获取100个元素。我使用以下JavaScript函数来解析和获取我的条目。

var fun = function(raw) {JSON.parse(raw).entries};

使用Nashorn运行一百万次调用需要7.5~7.8秒

(JSObject) invocable.invokeFunction("fun", json);

org.json耗时20~21秒

new JSONObject(JSON).getJSONArray("entries");

杰克逊耗时6.5~7秒

mapper.readValue(JSON, Entries.class).getEntries();

在这种情况下,杰克逊的表现比Nashorn好,后者的表现比org.json.好得多Nashorn API比org.json或Jackson的更难使用。根据您的需求,Jackson和Nashorn都是可行的解决方案。

您可以使用JsonNode作为JSON字符串的结构化树表示。它是无所不在的坚如磐石的杰克逊图书馆的一部分。

ObjectMapper mapper = new ObjectMapper();JsonNode yourObj = mapper.readTree("{\"k\":\"v\"}");

有许多开源库可以将JSON内容解析为对象,或者只是读取JSON值。您的要求只是读取值并将其解析为自定义对象。所以org.json库就足够了。

使用org.json库解析它并创建JsonObject:

JSONObject jsonObj = new JSONObject(<jsonStr>);

现在,使用这个对象来获取你的值:

String id = jsonObj.getString("pageInfo");

你可以在这里看到一个完整的例子:

如何解析JSON在Java

我们可以使用JSONObject类将JSON字符串转换为JSON对象,并遍历JSON对象。使用以下代码。

JSONObject jObj = new JSONObject(contents.trim());Iterator<?> keys = jObj.keys();
while( keys.hasNext() ) {String key = (String)keys.next();if ( jObj.get(key) instanceof JSONObject ) {System.out.println(jObj.getString(String key));}}

您可以使用Gson库来解析JSON字符串。

Gson gson = new Gson();JsonObject jsonObject = gson.fromJson(jsonAsString, JsonObject.class);
String pageName = jsonObject.getAsJsonObject("pageInfo").get("pageName").getAsString();String pagePic = jsonObject.getAsJsonObject("pageInfo").get("pagePic").getAsString();String postId = jsonObject.getAsJsonArray("posts").get(0).getAsJsonObject().get("post_id").getAsString();

您还可以循环遍历“帖子”数组,如下所示:

JsonArray posts = jsonObject.getAsJsonArray("posts");for (JsonElement post : posts) {String postId = post.getAsJsonObject().get("post_id").getAsString();//do something}

可以使用Apache@模型注释创建表示JSON文件结构的Java模型类,并使用它们来访问JSON树中的各种元素。与其他解决方案不同,这个工作完全没有反射适用于无法反射或有大量开销的环境。

有一个示例Maven项目显示了用法。首先它定义了结构:

@Model(className="RepositoryInfo", properties = {@Property(name = "id", type = int.class),@Property(name = "name", type = String.class),@Property(name = "owner", type = Owner.class),@Property(name = "private", type = boolean.class),})final class RepositoryCntrl {@Model(className = "Owner", properties = {@Property(name = "login", type = String.class)})static final class OwnerCntrl {}}

然后它使用生成的RepositoryInfo和Owner类来解析提供的输入流并在执行此操作时获取某些信息:

List<RepositoryInfo> repositories = new ArrayList<>();try (InputStream is = initializeStream(args)) {Models.parse(CONTEXT, RepositoryInfo.class, is, repositories);}
System.err.println("there is " + repositories.size() + " repositories");repositories.stream().filter((repo) -> repo != null).forEach((repo) -> {System.err.println("repository " + repo.getName() +" is owned by " + repo.getOwner().getLogin());})

就是这样!除此之外,这里还有一个活要点显示了类似的示例以及异步网络通信。

你需要使用jackson库中的JsonNode和ObjectMapper类来获取Json树的节点。

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.5</version></dependency>

你应该尝试下面的代码,这将工作:

import com.fasterxml.jackson.core.JsonGenerationException;import com.fasterxml.jackson.databind.JsonMappingException;import com.fasterxml.jackson.databind.JsonNode;import com.fasterxml.jackson.databind.ObjectMapper;
class JsonNodeExtractor{
public void convertToJson(){
String filepath = "c:\\data.json";ObjectMapper mapper = new ObjectMapper();JsonNode node =  mapper.readTree(filepath);
// create a JsonNode for every root or subroot element in the Json StringJsonNode pageInfoRoot = node.path("pageInfo");
// Fetching elements under 'pageInfo'String pageName =  pageInfoRoot.path("pageName").asText();String pagePic = pageInfoRoot.path("pagePic").asText();
// Now fetching elements under postsJsonNode  postsNode = node.path("posts");String post_id = postsNode .path("post_id").asText();String nameOfPersonWhoPosted = postsNode.path("nameOfPersonWhoPosted").asText();}}

jsoniter(jsoniterator)是一个相对较新的简单的json库,旨在简单快速。反序列化json数据需要做的就是

JsonIterator.deserialize(jsonData, int[].class);

其中jsonData是一个json数据字符串。

请查看官网链接更多信息

您可以使用帝斯曼流解析库来解析复杂的json和XML文档。DSM只解析一次数据,而不是将所有数据加载到内存中。

假设我们有类来反序列化给定的json数据。

页面类

public class Page {private String pageName;private String pageImage;private List<Sting> postIds;
// getter/setter
}

创建一个yaml映射文件。

result:type: object     # result is arraypath: /postsfields:pageName:path: /pageInfo/pageNamepageImage:path: /pageInfo/pagePicpostIds:path: post_idtype: array

使用DSM提取字段。

DSM dsm=new DSMBuilder(new File("path-to-yaml-config.yaml")).create(Page.class);Page page= (Page)dsm.toObject(new path-to-json-data.json");

页面变量序列化为json:

{"pageName" : "abc","pageImage" : "http://example.com/content.jpg","postIds" : [ "123456789012_123456789012" ]}

DSM非常适合复杂的json和xml。

有两个主要选项…

  1. 对象映射。当您将JSON数据反序列化为以下几个实例时:

    1.1。一些预定义的类,如Maps。在这种情况下,您不必设计自己的POJO类。一些库:org.json.simplehttps://www.mkyong.com/java/json-simple-example-read-and-write-json/

    1.2.您自己的POJO类。您必须设计自己的POJO类来呈现JSON数据,但如果您也要在业务逻辑中使用它们,这可能会有所帮助。一些库:Gson、Jackson(参见http://tutorials.jenkov.com/java-json/index.html

映射的主要倒退是它导致了密集的内存分配(和GC压力)和CPU利用率。

  1. 面向流的解析。例如,Gson和Jackson都支持这种轻量级解析。此外,您可以看一个自定义、快速和无GC解析器https://github.com/anatolygudkov/green-jelly的示例。如果您需要解析大量数据和延迟敏感应用程序,则更喜欢这种方式。

Jakarta(Java)Enterprise Edition 8包含JSON-B(用于JSON绑定的JavaAPI)。因此,如果您使用的是Jakarta EE 8服务器,例如Payara 5,JSON-B将开箱即用。

一个简单的例子,没有自定义配置:

public static class Dog {public String name;public int age;public boolean bites;}
// Create a dog instanceDog dog = new Dog();dog.name = "Falco";dog.age = 4;dog.bites = false;
// Create Jsonb and serializeJsonb jsonb = JsonbBuilder.create();String result = jsonb.toJson(dog);
// Deserialize backdog = jsonb.fromJson("{\"name\":\"Falco\",\"age\":4,\"bites\":false}", Dog.class);

您可以通过使用配置、注释、适配器和(反)序列化器来自定义映射

如果您不使用Jakarta EE 8,请始终使用安装JSON-B

如果你有maven项目,那么在依赖项下面添加或普通项目添加json-简单jar。

<dependency><groupId>org.json</groupId><artifactId>json</artifactId><version>20180813</version></dependency>

写下面的java代码将JSON字符串转换为JSON数组。

JSONArray ja = new JSONArray(String jsonString);

如果你的数据很简单,并且不需要外部依赖项,请使用几行代码:

/*** A very simple JSON parser for one level, everything quoted.* @param json the json content.* @return a key => value map.*/public static Map<String, String> simpleParseJson(String json) {Map<String, String> map = new TreeMap<>();String qs[] = json.replace("\\\"", "\u0001").replace("\\\\", "\\").split("\"");for (int i = 1; i + 3 < qs.length; i += 4) {map.put(qs[i].replace('\u0001', '"'), qs[i + 2].replace('\u0001', '"'));}return map;}

所以这些数据

{"name":"John", "age":"30", "car":"a \"quoted\" back\\slash car"}

生成包含

{age=30, car=a "quoted" back\slash car, name=John}

这也可以升级为使用未引用的值…

/*** A very simple JSON parser for one level, names are quoted.* @param json the json content.* @return a key => value map.*/public static Map<String, String> simpleParseJson(String json) {Map<String, String> map = new TreeMap<>();String qs[] = json.replace("\\\"", "\u0001").replace("\\\\",  "\\").split("\"");for (int i = 1; i + 1 < qs.length; i += 4) {if (qs[i + 1].trim().length() > 1) {String x = qs[i + 1].trim();map.put(qs[i].replace('\u0001', '"'), x.substring(1, x.length() - 1).trim().replace('\u0001', '"'));i -= 2;} else {map.put(qs[i].replace('\u0001', '"'), qs[i + 2].replace('\u0001', '"'));}}return map;}

为了解决复杂的结构,它变得丑陋……对不起!!!…但我无法抗拒编码它^^这解析给定的JSON问题和更多。它产生嵌套映射和列表。

/*** A very simple JSON parser, names are quoted.** @param json the json content.* @return a key => value map.*/public static Map<String, Object> simpleParseJson(String json) {Map<String, Object> map = new TreeMap<>();String qs[] = json.replace("\\\"", "\u0001").replace("\\\\", "\\").split("\"");int index[] = { 1 };recurse(index, map, qs);return map;}
/*** Eierlegende Wollmilchsau.** @param index index into array.* @param map   the current map to fill.* @param qs    the data.*/private static void recurse(int[] index, Map<String, Object> map, String[] qs) {int i = index[0];for (;; i += 4) {String end = qs[i - 1].trim(); // check for termination of an objectif (end.startsWith("}")) {qs[i - 1] = end.substring(1).trim();i -= 4;break;}
String key = qs[i].replace('\u0001', '"');String x = qs[i + 1].trim();if (x.endsWith("{")) {x = x.substring(0, x.length() - 1).trim();if (x.endsWith("[")) {List<Object> list = new ArrayList<>();index[0] = i + 2;for (;;) {Map<String, Object> inner = new TreeMap<>();list.add(inner);recurse(index, inner, qs);map.put(key, list);i = index[0];
String y = qs[i + 3]; // check for termination of arrayif (y.startsWith("]")) {qs[i + 3] = y.substring(1).trim();break;}}continue;}
Map<String, Object> inner = new TreeMap<>();index[0] = i + 2;recurse(index, inner, qs);map.put(key, inner);i = index[0];continue;}if (x.length() > 1) { // unquotedString value = x.substring(1, x.length() - 1).trim().replace('\u0001', '"');if ("[]".equals(value)) // handle empty arraymap.put(key, new ArrayList<>());elsemap.put(key, value);i -= 2;} else {map.put(key, qs[i + 2].replace('\u0001', '"'));}}index[0] = i;}

收益率-如果您打印地图:

{pageInfo={pageName=abc, pagePic=http://example.com/content.jpg}, posts=[{actor_id=1234567890, comments=[], likesCount=2, message=Sounds cool. Can't wait to see it!, nameOfPersonWhoPosted=Jane Doe, picOfPersonWhoPosted=http://example.com/photo.jpg, post_id=123456789012_123456789012, timeOfPost=1234567890}]}

任何类型的json数组解决问题的方法

  1. 将JSON对象转换为java对象。
  2. 您可以使用此链接或任何在线工具。
  3. 保存为像Myclass.java这样的java类。
  4. Myclass obj = new Gson().fromJson(JsonStr, Myclass.class);
  5. 使用obj,您可以获得您的值。