如何在Java中解析JSON


1048

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

7
java的内置JSON库是实现此目的的快捷方式,但以我的经验,GSON是将JSON轻松解析为POJO的最佳库。
伊曼·阿克巴里

16
这是第一个高度表决,其答案我发现最令人困惑的问题,保护
Riyafa阿卜杜勒·哈米德

6
@JaysonMinard同意。要求国防部干预。这应该真的关闭。最初,我以为(错误地)认为在问题得到保护的情况下我无法这样做,因此我取消了保护并做了我的事情。现在重新保护它,以防止在等待Mod时回复次数过少等问题。
梅纳

4
“这个问题没有表现出任何的研究工作” - Downvote按钮提示
让·弗朗索瓦·科贝特

6
这个问题正在Meta讨论
马克·阿默里

Answers:


753

org.json库易于使用。下面的示例代码:

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");
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


15
我同意@StaxMan。我刚刚尝试了org.json,这非常麻烦。例如,它实际上不适用于标准Java Collection类型。
肯·威廉姆斯

7
@StaxMan我会选择org.json其他库来进行简单的JSON解析,甚至不用看。这是Douglas Crockford(JSON发现器)创建的参考库。
奥马尔·伊萨维

31
@OmarIthawi真是愚蠢。这是笨拙的API的概念验证,实施效率低下。我认为最好是根据自己的优点考虑图书馆,而不是试图从作者的知名度中推论出质量-Doug已经取得了很多成就,但这并没有真正改变特定库的质量。10年前,它是城里唯一的游戏,但是从那以后,有了很多积极的进步。就像json库的Struts。
StaxMan

12
org.json是最差的json库之一。在选择之前,应该先查看可用json库的功能集和性能。这是我使用JMH比较jackson,gson,org.json,genson的基准:github.com/fabienrenaud/java-json-benchmark。杰克逊显然是这里的赢家。
fabien

4
该许可不包括任何常用的开源许可,并且还拥有版权。
Christian Vielma

536

为了便于说明,假设您有一个Person仅包含一个的类name

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

16
好答案。一个建议进行小幅改进:GSON和Jackson都支持使用JSON树表示形式(对于Jackson,这些是JsonNodes,GSON具有类似的含义)。最好显示片段,因为这类似于org.json提供的唯一方式。
StaxMan,2015年

另外两个值得一提(
出于

3
@NeonWarge,为什么?在我看来,这个答案假设一个人已经定义了一个Java类,该类包含与JSON字符串完全相同的字段,仅此而已。这是一个很强的假设。
Andrea Lazzarotto

1
json-simple和oracle的jsonp表现非常出色:github.com/fabienrenaud/java-json-benchmark为了提高性能,请选择jackson或dsljson。
fabien '16

GSON不支持除root之外的其他级别的字段动态过滤!
Gangnus '16

102
  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);
  2. 但是,如果只是想解析JSON字符串并获取一些值,(或从头开始创建JSON字符串以通过电线发送),只需使用包含JsonReader,JsonArray,JsonObject等的JaveEE jar。您可能要下载该实现规格,例如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");

4
@nondescript如果我不得不猜想我会说它被否决了,因为它没有回答原始张贴者的问题:“所需的代码是什么?” 赞成的答案提供了代码片段。
jewbix.cube 2015年

4
注意:Jackson和GSON都支持树样式和/或Maps / Lists绑定,因此不需要使用Java EE(javax.json)包。除了Jackson或GSON之外,javax.json几乎无所提供。
StaxMan 2015年

我建议添加一个指向JavaEE库的链接。
罗勒·布尔克

72

quick-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);

3
有可用的javadoc吗?
jboi

24
解析时,此程序包无法处理空值。例如:...“ description”:“” ...引发异常
Ivan 2013年

6
我已经在code.google.com/p/quick-json/issues/detail?id=11中修复了这个问题(以及许多其他问题), 希望作者花些时间在正式版本中修复它。
noamik 2014年

8
在列出的功能中,与其他选项相比,没有什么是唯一的-高性能的主张不受任何支持;不像更成熟文库(GSON,杰克逊,Genson,皇家),其被包括在像基准github.com/eishay/jvm-serializersgithub.com/novoj/JavaJsonPerformanceTestdeveloper.com/lang/jscript/... - I还没有看到该库包含在测试中,也没有提到它被广泛使用。
StaxMan 2014年

26
该项目似乎已死,似乎不再托管在中央Maven存储库中。
8bitjunkie 2015年

40

您可以使用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);

摇篮导入

记住要在应用程序Gradle文件中导入库

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

自动模型生成

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


38

在访问感兴趣的属性中的值之前,几乎所有给出的答案都需要将JSON完全反序列化为Java对象。另一个不走这条路的选择是使用JsonPATH,它类似于XPath for JSON,并允许遍历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的其他方法的更多信息。


这是一个非常好的库,尤其是用于读取和更新JSON的库,但是请注意有关此库的一些已知问题。参见[1]:github.com/json-path/JsonPath/issues/272 [2]:github.com/json-path/JsonPath/issues/375
papigee

38

A-说明

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

在您的JSON对象(实际上是一个复合对象)中,主要对象包含两个子对象。因此,我们的POJO类应该具有相同的层次结构。我将整个JSON对象称为Page对象。Page对象由PageInfo对象和Post对象数组组成。

因此,我们必须创建三个不同的POJO类。

  • Page Class,PageInfo Class和Post Instances 数组的组合
  • PageInfo
  • 职位类别

我使用的唯一软件包是Jackson ObjectMapper,我们要做的是绑定数据。

com.fasterxml.jackson.databind.ObjectMapper

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

  • 杰克逊核心-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;
    }

}

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

26

使用minimum-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>

pojo的外观如何?
杰西

对于Pojo,请使用gson。该库不支持。
Sakib Sami's

22

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


7
自从我回答以来,我开始使用Jackson,我认为它是用于JSON反序列化的最好的库之一。
Giovanni Botta 2014年

2
为什么他们重​​新使用JSONP来表示不同于带有Padding的JSON的东西?...
Chris Wesseling,2015年

@ChrisWesseling你是什么意思?
乔瓦尼·博塔

“用于JSON处理的Java API(JSON-P)”是您链接到的文档的标题。这让我感到困惑,因为我知道JSONP的含义。
克里斯·韦瑟林

1
@ChrisWesseling哦,这很令人困惑。这就是他们为规范选择的内容。但是正如我所说,我会直接去杰克逊。
乔瓦尼·博塔

22

由于尚未有人提及,因此这是使用Nashorn(Java 8的JavaScript运行时部分,但在Java 11中已弃用)的解决方案的开始。

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");

杰克逊需要6.5〜7秒

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

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


1
什么是单位“ "”?不是英寸?是几秒钟?分钟?
彼得·莫滕森

1
@PeterMortensen表示秒。既然不清楚,我将对其进行更改。感谢您的审查。
otonglet

2
不幸的是,Nashorn在Java 11中已弃用。JEP 335
米德纳

1
我知道Nashorn已过时,但是我喜欢这个答案,因为我不希望有任何依赖关系。但是,我不得不重做该示例:ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); engine.eval("var fun = function(raw) { return JSON.parse(raw); };"); Map<String, Object> json = (Map<String, Object>) ((Invocable) engine).invokeFunction("fun", jsonString);
kgibm

21

以下示例显示了如何读取问题中的文本,表示为“ jsonText”变量。该解决方案使用Java EE7 javax.json API(在其他一些答案中提到)。我将其添加为单独答案的原因是,以下代码显示了如何实际访问问题中显示的某些值。要使此代码运行,需要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或任何其他可用的第三方框架而拒绝回答这个问题之前,它是每个问题“必需代码”的一个示例,用于解析提供的文本。我很清楚,JDK 9并未考虑遵守当前标准JSR 353,因此,应将JSR 353规范与其他任何第三方的JSON处理实现一样对待。


15

这让我非常震惊。您可以将String保留JSON的值传递给默认org.json包中的JSONObject的构造函数。

JSONArray rootOfPage =  new JSONArray(JSONString);

做完了 放下麦克风。这也适用JSONObjects。在那之后,您只需要查看在对象上Objects使用get()方法的层次结构即可。


13
JSONArray类型不是J2SE JDK API的一部分,并且您没有说哪个API或第三方库提供了此类型。
很棒

2
这并不是说我会建议使用它,但我认为这是指从“org.json”包json.org/java。它曾经在良好的Java库可用之前使用,但这是在几年前(2008年或之前)
StaxMan 2015年

1
还是Brainmurphy1是指Android中的JSONArray
亚历山大·法伯

12

Java有许多可用的JSON库。

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

选择任何库通常应注意三件事:

  1. 性能
  2. 易于使用(代码易于编写且清晰易读)-具有功能。
  3. 对于移动应用:依赖性/罐子大小

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

对于1,请参阅以下基准测试:https : //github.com/fabienrenaud/java-json-benchmark我使用JMH做过进行了比较,它使用流比较(序列化器和反序列化器的性能(杰克逊,gson,genson,fastjson,org.json,jsonp))和databind API。对于2,您可以在Internet上找到许多示例。上面的基准也可以用作示例来源...

基准的快速总结:杰克逊性能比org.json好5到6倍,比GSON好2倍以上。

对于您的特定示例,以下代码使用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.
    }
}

如果您有任何疑问,请告诉我。


11

除了其他答案外,我建议将此在线开源服务jsonschema2pojo.org推荐用于从JSON或json模式快速生成GSON,Jackson 1.x或Jackson 2.x的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
         }
    ]
}

jsonschema2pojo.org为GSON产生:

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

9

如果您有一些表示JSON字符串(jsonString)的Java类(例如Message),则可以将Jackson JSON库用于:

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

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


9

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

    }
}

`


有关Gson的完整知识,请参考以下链接。 github.com/google/gson/blob/master/UserGuide.md
venkat

9

存在许多开放源代码库,可将JSON内容解析为对象或仅读取JSON值。您的要求只是读取值并将其解析为自定义对象。因此,对于您而言,org.json库就足够了。

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

JSONObject jsonObj = new JSONObject(<jsonStr>);

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

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

您可以在此处看到完整的示例:

如何在Java中解析JSON


您的所有答案似乎都包含指向该站点的链接。如果是垃圾邮件,请停止。如果不是,请为造成的混乱感到抱歉,但是我认为没有必要在所有答案中发布链接。
唐老鸭

1
很难给出答案,您可以在其中解释所有情况。像在这种情况下一样,如何读取json数组或多个json对象。即使我这样做,答案也会很长,而且人可能会感到困惑。因此,我提供了一个链接,其中给出了适当的解释,并提供了适当的示例。他可以选择访问,也可以仅使用我的解释。
lalitbhagtani

1
在我看来,您提供的链接仅演示了如何读取JSON。在哪里也可以找到有关如何使用JSON的信息?
Lampros Tzanetos

抱歉,但我不明白您的问题:-“以及如何使用JSON”
lalitbhagtani

7

请执行以下操作:

JSONParser jsonParser = new JSONParser();
JSONObject obj = (JSONObject) jsonParser.parse(contentString);
String product = (String) jsonObject.get("productId");

10
嗯,这是哪个图书馆?
斯图尔特

2
我认为他正在使用org.json.simple
Lasitha Yapa

7

您可以使用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();

您也可以这样循环遍历“ posts”数组:

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

5
{
   "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
}

9
请解释您的答案,因为只有代码的答案对他人的帮助远不及书面文档。请参阅“给男人一条鱼,您要给他喂一天;教一个男人条鱼,并且要给他喂一辈子”
Wai Ha Lee

最好提及这是针对“ org.json”库的。但是,我认为这不是一个很好的方法,因为它非常冗长,并且'org.json'lib本身已过时(缓慢,笨拙的API)。有更好的选择:可以使用GSON,Jackson,Boon和Genson。
StaxMan,2015年

5

阅读以下博客文章,Java JSON

这篇文章有点老了,但我仍然想回答您的问题。

第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();
}

有关更多参考,请参考以下链接


4

本页顶部的答案使用太简单的示例,例如具有一个属性的对象(例如{name:value})。我认为仍然简单但现实的例子可以帮助某人。

这是Google Translate 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;

4

首先,您需要选择一个实现库

JSON处理Java API(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库的版本1。强烈建议使用当前版本的Jackson库。
赫伯特·于

4

您可以使用Jayway JsonPath。以下是GitHub链接,其中包含源代码,pom详细信息和良好的文档。

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和posts之间的逗号。

步骤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

3

我有这样的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);

马文

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

2

可以使用Apache @Model批注创建表示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()
    );
})

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


2

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

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

其中jsonData是json数据字符串。

请访问官方网站 以获取更多信息。


1

我们可以使用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));
  }
}

2
这仅是机器人
卢博米尔


1
@DermotCanniffe它只是Android。
user4020527

1

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

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

页面类

public class Page {
    private String pageName;
    private String pageImage;
    private List<Sting> postIds;

    // getter/setter

}

创建一个Yaml映射文件。

result:
  type: object     # result is array
  path: /posts
  fields:
    pageName:
        path: /pageInfo/pageName
    pageImage:
        path: /pageInfo/pagePic
    postIds:
      path: post_id
      type: 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。


0

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

ObjectMapper mapper = new ObjectMapper();
JsonNode yourObj = mapper.readTree("{\"k\":\"v\"}");
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.