赞
踩
json文件大小为10G左右,对于这种超大的json使用jackson的objectmapper一把映射到java对象是不太可行的,内存一般都会溢出。此时需要使用jackson的JsonParser从文件中逐个token去读取。一般大json中都会存在某个数组中有超多的数据记录,我们需要解决的就是记录当前token路径,在读取到超大json数组时,再利用逐条数据读取mapper.readTree(jsonParser)逐条读取数据,利用数组缓存一定量的数据后,写入数据库后继续读取,知道json数组数据读取结束。
这里关键的是记录当前json的token的路径,以方便地利用mapper.readTree(jsonParser)读取任意的子节点数据。
- import com.fasterxml.jackson.core.JsonFactory;
- import com.fasterxml.jackson.core.JsonParser;
- import com.fasterxml.jackson.core.JsonToken;
- import com.fasterxml.jackson.databind.JsonNode;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import sarifreport.Result;
-
- import java.io.File;
- import java.io.IOException;
-
- public class Main {
- public static void main(String [] args){
- long start = System.currentTimeMillis();
- try {
- ObjectMapper mapper = new ObjectMapper();
- JsonFactory jsonFactory = new JsonFactory();
- JsonParser jsonParser = jsonFactory.createParser(
- new File("E:/result2.json"));
- JsonPath path = new JsonPath();
- while (jsonParser.nextToken() != null) {
- traverse(jsonParser, 0,path,mapper);
- }
- jsonParser.close();
- System.out.println((System.currentTimeMillis()-start)/1000+"秒");
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- private static void traverse(JsonParser jsonParser, int depth, JsonPath path, ObjectMapper mapper) throws IOException {
- JsonToken token = jsonParser.getCurrentToken();
-
- if (token == null) {
- return;
- }
- setPath(jsonParser,depth,path);
- if (path.toString().equals("root.runs[i].results[i]")) {
- while (jsonParser.nextToken() == JsonToken.START_OBJECT) {
- JsonNode jsonNode = mapper.readTree(jsonParser);
- // 此处可以读取一定数量的数据后入库
- System.out.println(jsonNode.toPrettyString());
- }
- token = jsonParser.getCurrentToken();
- }
- // Recursive call for nested structures
- if (token == JsonToken.START_OBJECT || token == JsonToken.START_ARRAY) {
- while (jsonParser.nextToken() != null && jsonParser.getCurrentToken() != JsonToken.END_OBJECT
- && jsonParser.getCurrentToken() != JsonToken.END_ARRAY) {
- traverse(jsonParser, depth + 1,path,mapper);
- }
- }
- }
-
- /**
- * 同一个depth只记录一个node
- * @param jsonParser
- * @param depth
- * @param path
- * @throws IOException
- */
- private static void setPath(JsonParser jsonParser, int depth, JsonPath path) throws IOException {
- JsonToken token = jsonParser.getCurrentToken();
- if (path.nodeLink.size() > depth+1) {
- path.nodeLink.subList(depth+1,path.nodeLink.size()).clear();
- }
- JsonPath.Node prefixNode = path.nodeLink.size()>=(depth+1)?path.nodeLink.get(depth):null;
- switch (token) {
- case FIELD_NAME:
- if (prefixNode != null) {
- prefixNode.nodeType = JsonPath.NODE_FIELD;
- prefixNode.nodeName = jsonParser.getCurrentName();
- } else {
- JsonPath.Node node = new JsonPath.Node();
- node.nodeType = JsonPath.NODE_FIELD;
- node.nodeName = jsonParser.getCurrentName();
- path.nodeLink.add(node);
- }
- break;
- case START_ARRAY:
- if (prefixNode != null && JsonPath.NODE_FIELD.equals(prefixNode.nodeType)) {
- prefixNode.nodeName = prefixNode.nodeName+"[i]";
- } else {
- JsonPath.Node node = new JsonPath.Node();
- node.nodeType = JsonPath.NODE_ARRAY;
- path.nodeLink.add(node);
- }
- break;
- case START_OBJECT:
- if (prefixNode != null && JsonPath.NODE_FIELD.equals(prefixNode.nodeType)) {
- prefixNode.nodeName = prefixNode.nodeName+".";
- } else {
- JsonPath.Node node = new JsonPath.Node();
- node.nodeType = JsonPath.NODE_OBJECT;
- path.nodeLink.add(node);
- }
- break;
- }
- }
- }
- import java.util.LinkedList;
-
- public class JsonPath {
- public static String NODE_ARRAY = "array";
- public static String NODE_OBJECT = "object";
- public static String NODE_FIELD = "field";
- public LinkedList<Node> nodeLink = new LinkedList<>();
-
- public static class Node{
- public String nodeName;
- public String nodeType;
- }
-
- @Override
- public String toString() {
- if (this.nodeLink == null || nodeLink.isEmpty()) {
- return "";
- }
- StringBuilder path = new StringBuilder();
- for (int i = 0; i < nodeLink.size(); i++ ) {
- Node node = this.nodeLink.get(i);
- if (node == null) {
- continue;
- }
- if (i == 0) {
- if (NODE_ARRAY.equals(node.nodeType)) {
- path.append("root[i]");
- } else {
- path.append("root");
- }
- }
- if (NODE_ARRAY.equals(node.nodeType)) {
- path.append("[i]");
- }else if (NODE_OBJECT.equals(node.nodeType)) {
- path.append(".");
- } else if (NODE_FIELD.equals(node.nodeType)) {
- path.append(node.nodeName);
- }
- }
- return path.toString();
- }
- }
- <?xml version="1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <groupId>org.example</groupId>
- <artifactId>BigJsonDeal</artifactId>
- <version>1.0-SNAPSHOT</version>
-
- <properties>
- <maven.compiler.source>19</maven.compiler.source>
- <maven.compiler.target>19</maven.compiler.target>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- </properties>
-
- <dependencies>
- <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- <version>2.16.1</version>
- </dependency>
- </dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.jsonschema2pojo</groupId>
- <artifactId>jsonschema2pojo-maven-plugin</artifactId>
- <version>1.2.1</version>
- <configuration>
- <sourceDirectory>${basedir}/src/main/resources/schema</sourceDirectory>
- <targetProject>${basedir}/src/main/java</targetProject>
- <targetPackage>com.example.types</targetPackage>
- </configuration>
- </plugin>
- </plugins>
- </build>
- </project>
jsonschema2pojo为一个根据json结构生成java的pojo代码的工具,对于复杂json生成pojo十分省时间。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。