我有以下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"
}
]
}
可以使用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()
);
})
就是这样!除此之外,这里还有一个生动的要点,展示了类似的例子以及异步网络通信。
您需要使用JsonNode和来自jackson库的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();
}
}
除了其他答案,我推荐这个在线开源服务jsonschema2pojo.org,它可以从json或json模式快速生成Java类,用于GSON, Jackson 1。或者Jackson 2.x。例如,如果你有:
{
"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;
}
主要有两种选择……
Object mapping. When you deserialize JSON data to a number of instances of:
1.1. Some predefined classes, like Maps. In this case, you don't have to design your own POJO classes. Some libraries: org.json.simple https://www.mkyong.com/java/json-simple-example-read-and-write-json/
1.2. Your own POJO classes. You have to design your own POJO classes to present JSON data, but this may be helpful if you are going to use them into your business logic as well. Some libraries: Gson, Jackson (see http://tutorials.jenkov.com/java-json/index.html)
映射的主要缺点是它会导致大量内存分配(以及GC压力)和CPU占用。
面向流的解析。例如,Gson和Jackson都支持这种轻量级解析。另外,您还可以查看一个自定义的、快速的、无gc的解析器示例https://github.com/anatolygudkov/green-jelly。在需要解析大量数据和对延迟敏感的应用程序中,更倾向于使用这种方式。