如何在Java中解析JSON

deyfvvtc  于 2022-09-16  发布在  Java
关注(0)|答案(30)|浏览(352)

我有以下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"
    }
  ]
}
cxfofazt

cxfofazt16#

org.json库易于使用。
请记住(在转换或使用getJSONObjectgetJSONArray等方法时)JSON符号中

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

示例代码如下:

import org.json.*;

String jsonString = ... ; //assign your JSON String here
JSONObject 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");
    ......
}

您可以从中找到更多示例:Parse JSON in Java
可下载jar:http://mvnrepository.com/artifact/org.json/json

waxmsbnn

waxmsbnn17#

如果您有一些表示JSON字符串(jsonString)的Java类(比如消息),则可以使用Jackson JSON库:

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

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

flmtquvp

flmtquvp18#

除了其他答案之外,我推荐这个在线开源服务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")
    @Expose
    public PageInfo pageInfo;
    @SerializedName("posts")
    @Expose
    public List<Post> posts = new ArrayList<Post>();
}

@Generated("org.jsonschema2pojo")
public class PageInfo {
    @SerializedName("pageName")
    @Expose
    public String pageName;
    @SerializedName("pagePic")
    @Expose
    public String pagePic;
}

@Generated("org.jsonschema2pojo")
public class Post {
    @SerializedName("post_id")
    @Expose
    public String postId;
    @SerializedName("actor_id")
    @Expose
    public long actorId;
    @SerializedName("picOfPersonWhoPosted")
    @Expose
    public String picOfPersonWhoPosted;
    @SerializedName("nameOfPersonWhoPosted")
    @Expose
    public String nameOfPersonWhoPosted;
    @SerializedName("message")
    @Expose
    public String message;
    @SerializedName("likesCount")
    @Expose
    public long likesCount;
    @SerializedName("comments")
    @Expose
    public List<Object> comments = new ArrayList<Object>();
    @SerializedName("timeOfPost")
    @Expose
    public long timeOfPost;
}
lsmepo6l

lsmepo6l19#

Java中有许多可用的JSON库。
最臭名昭著的是:Jackson、GSON、Genson、FastJson和org.json。
在选择任何库时,通常应注意以下三点:
1.性能
1.易于使用(代码编写简单易读)-与功能相匹配。
1.对于移动应用程序:依赖项/jar大小
特别是对于JSON库(以及任何序列化/反序列化库),数据绑定通常也很有趣,因为它不需要编写锅炉板代码来打包/解包数据。
对于1,请参阅这个基准:我使用JMH做的https://github.com/fabienrenaud/java-json-benchmark,它比较了使用流和数据绑定API的序列化器和反序列化器(jackson、gson、genson、fastjson、org.json、jsonp)的性能。对于2,你可以在互联网上找到许多例子。上面的基准也可以用作示例源。。。
基准测试的快速总结:*Jackson**的性能比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.
    }
}

如果你有任何问题,请告诉我。

cmssoen2

cmssoen220#

这件事如此简单,让我大吃一惊。您可以将保存JSON的String传递给默认org.JSON包中JSONObject的构造函数。

JSONArray rootOfPage =  new JSONArray(JSONString);

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

evrscar2

evrscar221#

我认为最佳实践应该是通过仍在进行中的官方Java JSON API

qzwqbdag

qzwqbdag22#

由于还没有人提到它,这里是使用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));
}

性能比较

我编写的JSON内容包含三个数组,分别包含20、20和100个元素。我只想从第三个数组中得到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");

Jackson需要6.5~7秒

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

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

6tr1vspr

6tr1vspr23#

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

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或任何其他可用的第三方框架而投票否决这个答案之前,这是每个问题的“必需代码”的一个示例,用于解析提供的文本。我很清楚,adherence to the current standard JSR 353 was not being considered for JDK 9JSR 353 spec应该与任何其他第三方JSON处理实现一样对待。

xfb7svmp

xfb7svmp24#

使用minimal-json,它非常快速且易于使用。您可以从字符串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);

梅文:

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

iqih9akk25#

几乎所有给出的答案都要求在访问感兴趣属性中的值之前将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的其他方法的更多信息。

kmpatx3s

kmpatx3s26#

A-解释

您可以使用Jackson库将JSON字符串绑定到POJO普通旧Java对象)示例。POJO只是一个只有私有字段和公共getter/setter方法的类。Jackson将遍历这些方法(使用反射),并将JSON对象Map到POJO示例中,因为类的字段名与JSON对象的字段名匹配。
在JSON对象中,它实际上是一个复合对象,主对象由两个子对象组成。因此,我们的POJO类应该具有相同的层次结构。我将整个JSON对象称为页面对象页面对象由PageInfo对象和Post对象数组组成。
因此,我们必须创建三个不同的POJO类;

*页面类,由PageInfo类和Post示例数组组成
*页面信息
*职位类别

我使用的唯一软件包是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类:Post

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;
    }

}

E-示例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 : abc
    Page Pic  : http://example.com/content.jpg
Page Posts;

**********

    Post Id                   : 123456789012_123456789012
    Actor Id                  : 1234567890
    Pic Of Person Who Posted  : http://example.com/photo.jpg
    Name Of Person Who Posted : Jane Doe
    Message                   : Sounds cool. Can't wait to see it!
    Likes Count               : 2
    Comments                  : []
    Time Of Post              : 1234567890
cgfeq70w

cgfeq70w27#

您可以使用Google Gson
使用这个库,您只需要创建一个具有相同JSON结构的模型。然后自动填充模型。您必须将变量称为JSON键,如果您想使用不同的名称,则使用@SerializedName

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 SerializedName
    private 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);

grad进口

记住在app Gradle文件中导入库

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

自动模型生成

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

yuvru6vn

yuvru6vn28#

quick-json parser非常简单、灵活、快速且可定制。试试看
特征:

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

它可以这样使用:

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

a0zr77ik29#

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

//from object to JSON 
Gson gson = new Gson();
gson.toJson(yourObject);

// from JSON to object 
yourObject o = gson.fromJson(JSONString,yourObject.class);

1.但是,如果您只想解析JSON字符串并获取一些值(或者从头创建JSON字符串以通过有线发送),只需使用JaveEE jar,它包含JsonReader、JsonArray、JsonObject等。您可能需要下载该规范的实现,如javax.JSON。通过这两个JAR,我能够解析json并使用值。
这些API实际上遵循XML的DOM/SAX解析模型。

Response response = request.get(); // REST call 
    JsonReader 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");
zengzsys

zengzsys30#

为了示例的目的,假设您有一个类**Person**,其中只有一个name

private class Person {
    public String name;

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

Google 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

JacksonMaven

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

System.out.println(user.name); //John

相关问题