【问题标题】:How to process JSON Array nested inside an Array in java如何在java中处理嵌套在数组中的JSON数组
【发布时间】:2018-10-28 04:33:30
【问题描述】:

这是一个 java 类 CreateDoc,它从一个作为生产者端的 Web 服务发送到另一个作为消费者端的 Web 服务,作为具有 content-type:Json 的列表

下面是类的表示

class CreateDoc{
     DocMetData dMetaData;
     DocContent dCont;
}

Class DocMetData {
     String docNamel
     String docType;
}

Class DocContent {
     String data;
}

一旦我在消费者端接收到 json 格式的 List,我就无法将其用作 java 对象,并且内容类型是数组,其中 json 嵌套在数组中。

以下是表示:

[  
   [  
      {  
         "dMetaData":{  
            "docName":"string",
            "docType":"pdf"
         },
         "dCont":{  
            "data":"abc"
         }
      },
      {  
         "dMetaData":{  
            "docName":"string",
            "docType":"pdf"

         },
         "dCont":{  
            "data":"def"
         }
      },
      {  
         "dMetaData":{  
            "docName":"string",
            "docType":"pdf"

         },
         "dCont":{  
            "data":"ghk"
         }
      }
   ]
]

问题是如何处理这个并能够使用数据并表示为列表。

【问题讨论】:

    标签: java json jackson


    【解决方案1】:

    这里有一些示例代码,展示了如何使用 Jackson ObjectMapper 来解析数据。请注意,代码假定数据存储在文件中,您可以根据需要对其进行修改。

    这是主类:

    package parsing.arrayofarray;
    
    import java.io.IOException;
    import java.nio.file.Files;
    import java.nio.file.Paths;
    import java.util.List;
    
    import com.fasterxml.jackson.core.JsonParseException;
    import com.fasterxml.jackson.core.type.TypeReference;
    import com.fasterxml.jackson.databind.JsonMappingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    public class ArrayOfArray {
    
        public static void main(String[] args) {
            ObjectMapper mapper = new ObjectMapper();
            String data = null;
            try {
                data = new String(Files.readAllBytes(Paths.get("src/main/resources/jsonArrayOfArray.json")));
            } catch (IOException e1) {
                e1.printStackTrace();
            }
    
            List<List<CreateDoc>> results = null;
    
            try {
                results = mapper.readValue(data, new TypeReference<List<List<CreateDoc>>>(){});
            } catch (JsonParseException e) {
                e.printStackTrace();
            } catch (JsonMappingException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            System.out.println(results);
        }
    
    }
    

    这里是支持类,首先是 CreateDoc:

    package parsing.arrayofarray;
    
    public class CreateDoc {
        DocMetData dMetaData;
        DocContent dCont;
        public DocMetData getdMetaData() {
            return dMetaData;
        }
        public void setdMetaData(DocMetData dMetaData) {
            this.dMetaData = dMetaData;
        }
        public DocContent getdCont() {
            return dCont;
        }
        public void setdCont(DocContent dCont) {
            this.dCont = dCont;
        }
        @Override
        public String toString() {
            return "CreateDoc [dMetaData=" + dMetaData + ", dCont=" + dCont + "]";
        }
    }
    

    和文档内容:

    package parsing.arrayofarray;
    
    public class DocContent {
        @Override
        public String toString() {
            return "DocContent [data=" + data + "]";
        }
    
        String data;
    
        public String getData() {
            return data;
        }
    
        public void setData(String data) {
            this.data = data;
        }
    }
    

    和 DocMetData:

    package parsing.arrayofarray;
    
    public class DocMetData {
        String docName;
        String docType;
        public String getDocNamel() {
            return docName;
        }
        public void setDocName(String docName) {
            this.docName = docName;
        }
        @Override
        public String toString() {
            return "DocMetData [docNamel=" + docName + ", docType=" + docType + "]";
        }
        public String getDocType() {
            return docType;
        }
        public void setDocType(String docType) {
            this.docType = docType;
        }
    }
    

    println 的输出是:

    [[CreateDoc [dMetaData=DocMetData [docNamel=string, docType=pdf], dCont=DocContent [data=abc]], CreateDoc [dMetaData=DocMetData [docNamel=string, docType=pdf], dCont=DocContent [data=def]], CreateDoc [dMetaData=DocMetData [docNamel=string, docType=pdf], dCont=DocContent [data=ghk]]]]
    

    【讨论】:

    • ObjectMapper 类型中的方法 readValue(JsonParser, Class) 的编译器错误不适用于参数 (List, new TypeReference>>( ){})
    • 看起来您向方法传递了错误的参数。如果您仔细查看我提供的代码,您会发现我将数据作为String 传递。该方法的输出是List&lt;List&lt;CreateDoc&gt;&gt;
    【解决方案2】:

    您可以使用 JSONArray(org.json) 解析第一个列表,并使用 GSON 解析内部列表以创建一个 CreatDoc 列表。你也可以只使用 GSON 来解析第一个数组

    import java.util.ArrayList;
    import java.util.List;
    
    import org.json.JSONArray;
    
    import com.google.common.reflect.TypeToken;
    import com.google.gson.Gson;
    
    public class Deserializer {
    
    public static void main(String[] args) {
        JSONArray jsonArray = new JSONArray(
                "[[{\"dMetaData\": {\"docName\": \"string\",\"docType\": \"pdf\"},\"dCont\": {\"data\": \"abc\"}},{\"dMetaData\": {\"docName\": \"string\",\"docType\": \"pdf\"},\"dCont\": {\"data\": \"def\"}},{\"dMetaData\": {\"docName\": \"string\",\"docType\": \"pdf\"},\"dCont\": {\"data\": \"ghk\"}}]]");
        JSONArray docsArray = jsonArray.getJSONArray(0);
        List<CreateDoc> docsList = new Gson().fromJson(docsArray.toString(),
                new TypeToken<ArrayList<CreateDoc>>() {}.getType());
        docsList.forEach(System.out::println);
    }
    
    public static class CreateDoc {
    
        DocMetData dMetaData;
        DocContent dCont;
    
        @Override
        public String toString() {
            return this.dMetaData.toString() + " " + this.dCont.toString();
        }
    }
    public static class DocMetData {
    
        String docName;
        String docType;
    
        @Override
        public String toString() {
            return "name: " + this.docName + " type: " + this.docType;
        }
    }
    public static class DocContent {
    
        String data;
    
        @Override
        public String toString() {
            return "data: " + this.data;
        }
    }
    

    }

    【讨论】:

    • 如果第一个数组里面有更多的数组,你可以使用foreach并应用相同的逻辑,这样更优雅,应该使用而不是总是使用第一个元素
    【解决方案3】:

    您可以使用GSON 将消息解析为带有 JSONObjects 的 JSONArray。然后为每个类创建一个解析器,将 JSONObject 中的字段转换为 Java 对象。 here有类似问题。

    【讨论】:

    • 谢谢,但这是封装在一个再次嵌套的数组中的 JSON。
    • 你可以解析数组,它也会解析所有嵌套的部分。看看here
    【解决方案4】:

    我认为问题在于您试图将 json 映射到 CreateDoc 而不是 CreateDoc 列表。如果您使用 spring boot 来管理应用程序中的 rest 层,请在方法中使用 @Requestbody List CreateDoc 来转换您的 json。这将在内部使用 Jackson 转换器。否则,您可以使用 Jackson 转换器 jar 将您的 json 转换为对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-23
      • 1970-01-01
      • 2019-11-01
      • 2020-10-15
      • 1970-01-01
      • 1970-01-01
      • 2020-05-19
      • 2018-02-04
      相关资源
      最近更新 更多