提问人:Muhammad Maqsoodur Rehman 提问时间:4/7/2010 最后编辑:banan3'14Muhammad Maqsoodur Rehman 更新时间:7/8/2023 访问量:2418916
如何在 Java 中解析 JSON
How to parse JSON in Java
问:
我有以下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"
}
]
}
答:
Quick-JSON 解析器非常简单、灵活、非常快速且可定制。尝试一下
特征:
- 符合JSON规范(RFC4627)
- 高性能 JSON 解析器
- 支持灵活/可配置的解析方法
- 对任何 JSON 层次结构的键/值对进行可配置验证
- 易于使用 # 占用空间极小
- 提高开发人员友好且易于跟踪的异常
- 可插入的自定义验证支持 - 可以通过在遇到自定义验证器时配置自定义验证器来验证键/值
- 验证和非验证解析器支持
- 支持两种类型的配置 (JSON/XML),以便使用 quick-JSON 验证解析器
- 需要 JDK 1.5
- 不依赖外部库
- 支持通过对象序列化生成 JSON
- 支持在解析过程中选择集合类型
它可以像这样使用:
JsonParserFactory factory=JsonParserFactory.getInstance();
JSONParser parser=factory.newJsonParser();
Map jsonMap=parser.parseJson(jsonString);
评论
我认为最好的做法应该是通过仍在开发中的官方 Java JSON API。
评论
org.json 库易于使用。
只需记住(在转换或使用 和 等方法时)在 JSON 表示法中getJSONObject
getJSONArray
[ … ]
表示一个数组,因此库会将其解析为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
可下载的罐子:http://mvnrepository.com/artifact/org.json/json
评论
org.json
这让我大吃一惊,因为它是多么容易。只需将 JSON 传递给默认 org.json 包中 JSONObject 的构造函数即可。String
JSONArray rootOfPage = new JSONArray(JSONString);
做。掉落麦克风。
这也适用于。之后,您可以查看在对象上使用方法的层次结构。JSONObjects
Objects
get()
评论
JSONArray
如果要从 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);
但是,如果只想解析 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");
评论
请做这样的事情:
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
}
评论
为了这个例子,我们假设你有一个类 Person
,只有一个 .name
private class Person {
public String name;
public Person(String name) {
this.name = name;
}
}
杰克逊(Maven)
我个人的最爱,也可能是最广泛使用的。
ObjectMapper mapper = new ObjectMapper();
// De-serialize to an object
Person user = mapper.readValue("{\"name\": \"John\"}", Person.class);
System.out.println(user.name); //John
// Read a single attribute
JsonNode nameNode = mapper.readTree("{\"name\": \"John\"}");
System.out.println(nameNode.get("name").asText());
谷歌 GSON (Maven)
Gson g = new Gson();
// De-serialize to an object
Person person = g.fromJson("{\"name\": \"John\"}", Person.class);
System.out.println(person.name); //John
// Read a single attribute
JsonObject jsonObject = new JsonParser().parse("{\"name\": \"John\"}").getAsJsonObject();
System.out.println(jsonObject.get("name").getAsString()); //John
Org.JSON (Maven)
这里列出了这个建议,只是因为它似乎很受欢迎,因为 stackoverflow 引用了它。我不建议使用它,因为它更像是一个概念验证项目,而不是一个实际的库。
JSONObject obj = new JSONObject("{\"name\": \"John\"}");
System.out.println(obj.getString("name")); //John
评论
JsonNode
new JsonParser().parse()
JsonParser.parseString()
如果你有一些 Java 类(比如 Message)表示 JSON 字符串 (jsonString),你可以将 Jackson JSON 库与:
Message message= new ObjectMapper().readValue(jsonString, Message.class);
从 Message 对象中,您可以获取它的任何属性。
几乎所有给出的答案都需要将 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")
@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;
}
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();
}
}
}
`
评论
阅读以下博客文章 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();
}
如需进一步参考,您可以参考以下链接。
下面的示例演示如何读取问题中的文本,表示为“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 处理实现相同。
您可以使用 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 导入
请记住在应用 Gradle 文件中导入库
implementation 'com.google.code.gson:gson:2.8.6' // or earlier versions
自动模型生成
您可以使用这样的在线工具自动从 JSON 生成模型。
Java 中有许多可用的 JSON 库。
最臭名昭著的是:Jackson、GSON、Genson、FastJson 和 org.json。
在选择任何库时,通常应该考虑三件事:
- 性能
- 易用性(代码编写简单且清晰易读)——这与功能相得益彰。
- 对于移动应用:依赖项/jar 大小
特别是对于 JSON 库(以及任何序列化/反序列化库),数据绑定通常也很重要,因为它消除了编写样板代码来打包/解压缩数据的需要。
对于 1,请参阅以下基准测试: https://github.com/fabienrenaud/java-json-benchmark 我使用 JMH 所做的,它比较了使用流和数据绑定 API 的序列化程序和解序列化程序(jackson、gson、genson、fastjson、org.json、jsonp)的性能。 对于 2,您可以在 Internet 上找到许多示例。上面的基准测试也可以用作示例的来源......
快速了解基准测试: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.
}
}
如果您有任何问题,请告诉我。
A - 解释
您可以使用 Jackson 库将 JSON 字符串绑定到 POJO(普通旧 Java 对象)实例中。POJO 只是一个只有私有字段和公共 getter/setter 方法的类。Jackson 将遍历这些方法(使用反射),并将 JSON 对象映射到 POJO 实例中,因为类的字段名称适合 JSON 对象的字段名称。
在 JSON 对象(实际上是一个复合对象)中,主对象由两个子对象组成。因此,我们的 POJO 类应该具有相同的层次结构。我将整个 JSON 对象称为 Page 对象。Page 对象由一个 PageInfo 对象和一个 Post 对象数组组成。
因此,我们必须创建三个不同的 POJO 类;
- 页类,PageInfo 类和 Post 实例数组的复合体
- 页面信息类
- 职位类
我唯一用过的包是 Jackson ObjectMapper,我们做的是绑定数据;
com.fasterxml.jackson.databind.ObjectMapper
下面列出了所需的依赖项,jar 文件;
- 杰克逊核心-2.5.1.jar
- 杰克逊数据绑定-2.5.1.jar
- 杰克逊注释-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
评论
此页面上的热门答案使用过于简单的示例,例如具有一个属性的对象(例如 {name: value})。我认为这个仍然简单但现实生活中的例子可以帮助某人。
所以这是谷歌翻译 API 返回的 JSON:
{
"data":
{
"translations":
[
{
"translatedText": "Arbeit"
}
]
}
}
我想使用 Google 的 Gson 检索“translatedText”属性的值,例如“Arbeit”。
两种可能的方法:
仅检索一个需要的属性
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();
从 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。下面是一个 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 和帖子之间的逗号。
第 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
使用 minimal-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>
首先,您需要选择一个实现库来执行此操作。
Java API for JSON Processing (JSR 353) 提供了可移植的 API,用于使用对象模型和流式 API 解析、生成、转换和查询 JSON。
参考实现如下:https://jsonp.java.net/
在这里,您可以找到 JSR 353 的实现列表:
为了帮助您做出决定......我也找到了这篇文章:
http://blog.takipi.com/the-ultimate-json-library-json-simple-vs-gson-vs-jackson-vs-json/
如果你选择 Jackson,这里有一篇关于使用 Jackson 在 Java 之间转换 JSON 和 Java 之间的转换的好文章: https://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson/
希望对您有所帮助!
评论
由于还没有人提到它,这里是使用 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 都可以成为可行的解决方案。
评论
"
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);
Object
ScriptObjectMirror
可用于 JSON 字符串的结构化树表示形式。它是无处不在的坚如磐石的杰克逊图书馆的一部分。JsonNode
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");
您可以在此处查看完整示例:
评论
我们可以使用 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();
您也可以按如下方式遍历“posts”数组:
JsonArray posts = jsonObject.getAsJsonArray("posts");
for (JsonElement post : posts) {
String postId = post.getAsJsonObject().get("post_id").getAsString();
//do something
}
可以使用 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()
);
})
就是这样!除此之外,这里还有一个实时要点,显示了类似的示例以及异步网络通信。
您需要使用 jackson 库中的 JsonNode 和 ObjectMapper 类来获取 Json 树的节点。在 pom.xml 中添加以下依赖项以获取对 Jackson 类的访问。
<!-- 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 String
JsonNode pageInfoRoot = node.path("pageInfo");
// Fetching elements under 'pageInfo'
String pageName = pageInfoRoot.path("pageName").asText();
String pagePic = pageInfoRoot.path("pagePic").asText();
// Now fetching elements under posts
JsonNode 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);
其中 是 JSON 数据的字符串。jsonData
查看官方网站以获取更多信息。
您可以使用 DSM 流解析库来解析复杂的 json 和 XML 文档。DSM 只解析一次数据,不会将所有数据加载到内存中。
假设我们有 Page 类来反序列化给定的 json 数据。
Page 类
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。
有 2 个主要选项......
对象映射。将 JSON 数据反序列化为以下多个实例时:
1.1. 一些预定义的类,如地图。在这种情况下,您不必设计自己的 POJO 类。一些库:org.json.simple https://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 利用率。
- 面向流的解析。例如,Gson 和 Jackson 都支持这种轻量级解析。此外,您还可以查看自定义、快速且无 GC 的解析器 https://github.com/anatolygudkov/green-jelly 示例。如果您需要解析大量数据和对延迟敏感的应用程序,请首选这种方式。
Jakarta (Java) Enterprise Edition 8 包括 JSON-B(用于 JSON 绑定的 Java API)。因此,如果您使用的是 Jakarta EE 8 服务器,例如 Payara 5,则 JSON-B 将开箱即用。
一个简单的例子,没有自定义配置:
public static class Dog {
public String name;
public int age;
public boolean bites;
}
// Create a dog instance
Dog dog = new Dog();
dog.name = "Falco";
dog.age = 4;
dog.bites = false;
// Create Jsonb and serialize
Jsonb jsonb = JsonbBuilder.create();
String result = jsonb.toJson(dog);
// Deserialize back
dog = jsonb.fromJson("{\"name\":\"Falco\",\"age\":4,\"bites\":false}", Dog.class);
您可以使用配置、注释、适配器和(反)序列化程序来自定义映射。
如果您使用的不是 Jakarta EE 8,则始终可以安装 JSON-B。
如果您有 maven 项目,请添加以下依赖项或普通项目,添加 json-simple 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 object
if (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 array
if (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) { // unquoted
String value = x.substring(1, x.length() - 1).trim().replace('\u0001', '"');
if ("[]".equals(value)) // handle empty array
map.put(key, new ArrayList<>());
else
map.put(key, value);
i -= 2;
} else {
map.put(key, qs[i + 2].replace('\u0001', '"'));
}
}
index[0] = i;
}
yields - 如果打印地图:
{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 数组 解决问题的步骤。
- 将 JSON 对象转换为 java 对象。
- 您可以使用此链接或任何在线工具。
- 另存为 java 类,如 .
Myclass.java
Myclass obj = new Gson().fromJson(JsonStr, Myclass.class);
- 使用 ,您可以获取您的值。
obj
评论