如何在java中解析json

fnx2tebb  于 2021-07-12  发布在  Java
关注(0)|答案(17)|浏览(393)

我有以下json文本。如何解析它以获得 pageName , pagePic , post_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"
             }
        ]
    }
jfgube3f

jfgube3f1#

现在有许多开源库可以将json内容解析为对象或只是读取json值。您的需求只是读取值并将其解析为自定义对象。所以org.json库就足够了。
使用org.json库解析并创建jsonobject:

JSONObject jsonObj = new JSONObject(<jsonStr>);

现在,使用此对象获取值:

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

您可以看到一个完整的示例h

mccptt67

mccptt672#

gson易于学习和实现,我们需要知道以下两种方法
tojson()–将java对象转换为json格式
fromjson()–将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 object
        DataObject obj = gson.fromJson(br, DataObject.class);

        System.out.println(obj);

    } catch (IOException e) {
        e.printStackTrace();
    }

    }
}

`

23c0lvtd

23c0lvtd3#

如果您有一些表示json字符串(jsonstring)的java类(比如message),那么您可以将jackson json库用于:

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

您可以从message对象获取它的任何属性。

kuhbmx9i

kuhbmx9i4#

由于还没有人提到它,下面是使用nashorn(javascript运行时是java8的一部分,但在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好,后者比org.json好得多。nashornapi比org.json或jackson更难使用。根据您的需求,jackson和nashorn都是可行的解决方案。

ql3eal8s

ql3eal8s5#

除了其他答案之外,我推荐这个在线开源服务jsonschema2pojo.org,用于从json或gson、jackson1.x或jackson2.x的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;
}
4c8rllxm

4c8rllxm6#

java中有许多可用的json库。
最臭名昭著的是:jackson、gson、genson、fastjson和org.json。
在选择任何库时,通常应注意以下三点:
演出
易用性(代码编写简单易读)-这与功能相匹配。
对于移动应用程序:依赖项/jar大小
特别是对于json库(以及任何序列化/反序列化lib),数据绑定通常也很有趣,因为它不需要编写锅炉板代码来打包/解包数据。
对于1,请参见以下基准:https://github.com/fabienrenaud/java-json-benchmark 我使用jmh来比较(jackson、gson、genson、fastjson、org.json、jsonp)使用流和数据绑定api的序列化程序和反序列化程序的性能。对于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.
    }
}

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

ymdaylpp

ymdaylpp7#

这件事太容易了,让我大吃一惊。你可以通过一个 String 将json保存到默认org.json包中jsonobject的构造函数中。

JSONArray rootOfPage =  new JSONArray(JSONString);

完成。放下麦克风。这适用于 JSONObjects 也。在那之后,你可以看看你的等级制度 Objects 使用 get() 对象上的方法。

1qczuiv0

1qczuiv08#

下面的示例显示如何读取问题中的文本,用“jsontext”变量表示。这个解决方案使用javaee7javax.jsonapi(在其他一些答案中提到)。我之所以添加它作为一个单独的答案,是因为下面的代码显示了如何实际访问问题中显示的一些值。运行此代码需要javax.jsonapi的实现。因为我不想声明“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或其他任何第三方框架而对它投反对票之前,它是每个问题的“必需代码”的一个例子,用于解析提供的文本。我很清楚,jdk9没有考虑遵守当前的标准jsr353,因此jsr353规范应该与任何其他第三方json处理实现一样对待。

xjreopfe

xjreopfe9#

我相信最好的实践应该是通过官方的javajsonapi,它仍在进行中。

mccptt67

mccptt6710#

org.json库易于使用。
只要记住(当铸造或使用像 getJSONObject 以及 getJSONArray )用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");
    ......
}

您可以从以下内容中找到更多示例:在java中解析json
可下载jar:http://mvnrepository.com/artifact/org.json/json

6rqinv9w

6rqinv9w11#

使用最简单的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);

Maven:

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

mmvthczy12#

a-解释

您可以使用jackson库将json字符串绑定到pojo(普通旧java对象)示例中。pojo只是一个只有私有字段和公共getter/setter方法的类。jackson将遍历这些方法(使用反射),并将json对象Map到pojo示例中,因为类的字段名与json对象的字段名相匹配。
在json对象(实际上是一个复合对象)中,主对象由两个子对象组成。因此,我们的pojo类应该具有相同的层次结构。我将整个json对象称为page对象。page对象由pageinfo对象和post对象数组组成。
所以我们必须创建三个不同的pojo类;
page类,pageinfo类和post示例数组的组合
pageinfo类
posts类
我唯一使用的包是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-child 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-child 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-sample 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
ipakzgxi

ipakzgxi13#

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

k4ymrczo

k4ymrczo14#

你可以使用googlegson。
使用这个库,您只需要创建一个具有相同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);

渐变导入

记住在app gradle文件中导入库

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

模型自动生成

您可以使用这样的在线工具从json自动生成模型。

of1yzvn4

of1yzvn415#

快速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);

相关问题