使用杰克逊创建一个 json 对象

Posted

技术标签:

【中文标题】使用杰克逊创建一个 json 对象【英文标题】:Creating a json object using jackson 【发布时间】:2013-06-03 04:37:05 【问题描述】:

如何使用 jackson 创建一个 json 数组,如下例所示。

我尝试使用 ObjectMapper,但这似乎不正确。

      try (DirectoryStream<Path> ds = Files.newDirectoryStream(path)) 
            for (Path file : ds) 
                System.out.println("name:"+file.getFileName()+
                        "\n"+
                        "mime:"+Files.probeContentType(file)+
                "\n"+
                "locked:"+!Files.isWritable(file));
            
         catch (IOException e) 
            System.err.println(e);
        

最终我将制作一个具有以下值的 json。

 * - (int)    size    file size in b. required
 * - (int)    ts      file modification time in unix time. required
 * - (string) mime    mimetype. required for folders, others - optionally
 * - (bool)   read    read permissions. required
 * - (bool)   write   write permissions. required
 * - (bool)   locked  is object locked. optionally
 * - (bool)   hidden  is object hidden. optionally
 * - (string) alias   for symlinks - link target path relative to root path. optionally
 * - (string) target  for symlinks - link target path. optionally

这是我提供的一个示例 json。

"files": [
    
        "mime": "directory",
        "ts": 1334071677,
        "read": 1,
        "write": 0,
        "size": 0,
        "hash": "l1_Lw",
        "volumeid": "l1_",
        "name": "Demo",
        "locked": 1,
        "dirs": 1
    ,
    
        "mime": "directory",
        "ts": 1334071677,
        "read": 1,
        "write": 0,
        "size": 0,
        "hash": "l1_Lw",
        "volumeid": "l1_",
        "name": "Demo",
        "locked": 1,
        "dirs": 1
    ,
    
        "mime": "directory",
        "ts": 1340114567,
        "read": 0,
        "write": 0,
        "size": 0,
        "hash": "l1_QmFja3Vw",
        "name": "Backup",
        "phash": "l1_Lw",
        "locked": 1
    ,
    
        "mime": "directory",
        "ts": 1310252178,
        "read": 1,
        "write": 0,
        "size": 0,
        "hash": "l1_SW1hZ2Vz",
        "name": "Images",
        "phash": "l1_Lw",
        "locked": 1
    ,
    
        "mime": "application\/x-genesis-rom",
        "ts": 1310347586,
        "read": 1,
        "write": 0,
        "size": 3683,
        "hash": "l1_UkVBRE1FLm1k",
        "name": "README.md",
        "phash": "l1_Lw",
        "locked": 1
    
]

编辑 1

        Map<String, Object> filesMap = new HashMap<>();
        List<Object> files = new ArrayList<Object>();
        System.out.println("\nNo filter applied:");
        try (DirectoryStream<Path> ds = Files.newDirectoryStream(path)) 
            for (Path file : ds) 
                Map<String, Object> fileInfo = new HashMap<>();
                fileInfo.put("name", file.getFileName().toString());
//                Prints Files in Director
//                Files.getAttribute(file,"size");
                System.out.println("name:" + file.getFileName().toString() +
                        "\n" +
                        "mime:" + Files.probeContentType(file) +
                        "\n" +
                        "locked:" + !Files.isWritable(file));
                ObjectMapper mapper = new ObjectMapper();
                String json = mapper.writeValueAsString(fileInfo);
                files.add(json);
            
         catch (IOException e) 
            System.err.println(e);
        
        files.toArray();
        filesMap.put("files", files);
        ObjectMapper mapper = new ObjectMapper();
        String jsonString;
        try 
            jsonString = mapper.writeValueAsString(filesMap);
         catch (IOException e) 
            jsonString = "fail";  //To change body of catch statement use File | Settings | File Templates.
        

输出以下更接近的json,但我无法弄清楚为什么之前和之后的额外引号。

"files":["\"name\":\"32C92124-EFCF-42C1-AFD2-8B741AE6854B.jpg\"","\"name\":\"58D5B83F-4065-4D6E-92BE-8181D99CB6CB.jpg\"","\"name\":\"7B1464A0-FBA1-429E-8A39-3DE5B539FBF8.jpg\"","\"name\":\"888159CF-45BE-475F-8C6A-64B3E1D97278.jpg\""]

最终答案

    Map<String, Object> filesMap = new HashMap<>();
    List<Object> files = new ArrayList<Object>();
    System.out.println("\nNo filter applied:");
    try (DirectoryStream<Path> ds = Files.newDirectoryStream(path)) 
        for (Path file : ds) 
            Map<String, Object> fileInfo = new HashMap<>();
            fileInfo.put("name", file.getFileName().toString());
            System.out.println("name:" + file.getFileName().toString() +
                    "\n" +
                    "mime:" + Files.probeContentType(file) +
                    "\n" +
                    "locked:" + !Files.isWritable(file));
            files.add(fileInfo);
        
     catch (IOException e) 
        System.err.println(e);
    
    files.toArray();
    filesMap.put("files", files);
    ObjectMapper mapper = new ObjectMapper();
    String jsonString;
    try 
        jsonString = mapper.writeValueAsString(filesMap);
     catch (IOException e) 
        jsonString = "fail"; 
    

【问题讨论】:

您的问题似乎缺少一个实际问题。 对不起,今晚我遇到了太多的互联网问题,我想我忘了补充。 :P 现在更有意义了吗? 我很困惑。这里没有明显使用ObjectMapper。您是想将某些内容转换为使用ObjectMapper 还是什么? 您已经显示了您想要的输入和输出,但没有您实际尝试过的内容:实际转换代码。你读过Jackson in Five Minutes tutorial吗? 我浏览了教程,它很有帮助,虽然还没有,但已经接近了。 【参考方案1】:

你需要一个JsonNodeFactory:

final JsonNodeFactory factory = JsonNodeFactory.instance;

这个类有创建ArrayNodes、ObjectNodes、IntNodes、DecimalNodes、TextNodes等等的方法。 ArrayNodes 和 ObjectNodes 具有方便的突变方法,可以直接添加大多数 JSON 原始(非容器)值,而无需通过工厂(嗯,在内部,它们引用了这个工厂,这就是原因)。

对于ObjectMapper,请注意它既是序列化器(ObjectWriter)又是反序列化器(ObjectReader)。

【讨论】:

实际上将这个作为答案,因为当我给它信用时,另一个答案引起了不可预见的问题。这是我使用的最终答案:)【参考方案2】:

您可以将对象写入 json 字符串。因此,我希望您将数据保存在根据您的需要定义的类的对象中。以下是如何将该对象转换为 json 字符串的方法:

//1. Convert Java object to JSON format
ObjectMapper mapper = new ObjectMapper();

String jsonString = mapper.writeValueAsString(yourObject);

请参阅 here 以获取完整的 jackson-databind javadoc。

【讨论】:

这让我非常接近,但由于某种原因,我在子对象周围有额外的引号。我添加了我目前在上面的内容。 @DirkLachowski 是的 :) 我把它放在 EDIT 1 下的描述底部 额外的引号是因为我使用了两次 ObjectMapper。删除内部 writeValueAsString 后,我能够得到预期的结果。感谢您的帮助。【参考方案3】:

将 JSON 对象初始化为单例实例并构建它:

ObjectNode node = JsonNodeFactory.instance.objectNode(); // initializing
node.put("x", x); // building

PS:打印使用node.toString()

【讨论】:

【参考方案4】:

您可以在不创建 POJO 并将其转换为 JSON 的情况下执行此操作。我假设您的数据在 Record 对象中。

        JsonNode rootNode = mapper.createObjectNode();
        ArrayNode childNodes = mapper.createArrayNode();
        for (Record record : records) 
            JsonNode element = mapper.createObjectNode();
            ((ObjectNode) element).put("mime": record.getDirectory());
                  //fill rest of fields which are needed similar to this.
                  //Also here record.getDirectory() method will should return "directory"
                  //according to your json file.
            childNodes.add(element);
        
        ((ObjectNode) rootNode).put("files", childNodes);

【讨论】:

以上是关于使用杰克逊创建一个 json 对象的主要内容,如果未能解决你的问题,请参考以下文章

JSON 使用杰克逊库相同对象的字段,但在必要时打印不同的值

无法使用杰克逊反序列化包含 2 个具有相同 ID 的对象的 Json

不要将空对象包括给杰克逊

对象序列化到字节与杰克逊序列化从对象到 JSON?

杰克逊:了解源JSON是数组还是对象

Jackson:映射嵌套对象