You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java使用Jackson序列化生成JSON格式不符合预期问题求助

问题原因
  • 重复序列化:你先调用writeValueAsString()将Post对象转为JSON字符串,随后又将该字符串作为参数传入writeValue()方法写入文件,相当于对字符串做了二次序列化,导致外层多了引号、内部引号被转义。
  • Comment类不符合JavaBean序列化要求:输出中comments数组里是Comment(id=1, user=Zoli...)这类toString()的输出,说明Jackson无法识别Comment类的属性,大概率是Comment类的私有属性没有提供public的getter方法,导致Jackson只能调用toString()输出内容。
  • 输出结构不匹配:你期望的输出最外层是包含posts数组的对象,当前代码直接序列化单个Post对象,自然没有外层的posts字段包裹。
  • 枚举输出不符合要求:默认情况下Jackson会直接输出枚举常量的名称(大写),和你期望的小写自定义值不匹配。
解决方案

1. 调整实体类代码

确保Post、Comment类都为私有属性添加public getter方法,枚举类添加@JsonValue注解自定义输出值:

// Status枚举类
import com.fasterxml.jackson.annotation.JsonValue;

public enum Status {
    IN_PROGRESS("in_progress"),
    DONE("done");

    private final String desc;

    Status(String desc) {
        this.desc = desc;
    }

    // 序列化时直接返回desc字段的值
    @JsonValue
    public String getDesc() {
        return desc;
    }
}
// Comment类示例
public class Comment {
    private String id;
    private String user;
    private String date;
    private String description;

    // 此处省略所有setter方法,请保留原有setter
    // 必须添加以下getter方法供Jackson读取属性
    public String getId() { return id; }
    public String getUser() { return user; }
    public String getDate() { return date; }
    public String getDescription() { return description; }
}
// Post类示例
public class Post {
    private Integer id;
    private String title;
    private String user;
    private String date;
    private Status status;
    private String description;
    private List<Comment> comments;

    // 此处省略所有setter方法,请保留原有setter
    // 必须添加以下getter方法供Jackson读取属性
    public Integer getId() { return id; }
    public String getTitle() { return title; }
    public String getUser() { return user; }
    public String getDate() { return date; }
    public Status getStatus() { return status; }
    public String getDescription() { return description; }
    public List<Comment> getComments() { return comments; }
}

2. 调整主类序列化逻辑

构造符合预期的外层包裹结构,避免重复序列化:

import com.fasterxml.jackson.core.util.DefaultIndenter;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Main {
    public static void main(String[] args) throws IOException {
        List<Comment> comments = new ArrayList<>();
        // 构造测试评论数据
        Comment comm1 = new Comment();
        comm1.setId("1");
        comm1.setUser("Zoli");
        comm1.setDate("22/09/2021");
        comm1.setDescription("Very nice!");
        comments.add(comm1);

        Comment comm2 = new Comment();
        comm2.setId("2");
        comm2.setUser("Krisz");
        comm2.setDate("22/09/2021");
        comm2.setDescription("Nice!");
        comments.add(comm2);

        Comment comm3 = new Comment();
        comm3.setId("3");
        comm3.setUser("Csaba");
        comm3.setDate("22/09/2021");
        comm3.setDescription("Very good!");
        comments.add(comm3);

        Comment comm4 = new Comment();
        comm4.setId("4");
        comm4.setUser("Márk");
        comm4.setDate("22/09/2021");
        comm4.setDescription("Good!");
        comments.add(comm4);

        // 构造测试Post数据
        Post post = new Post();
        post.setId(1);
        post.setTitle("Example");
        post.setUser("Ruben");
        post.setDate("22/09/2021");
        post.setStatus(Status.DONE);
        post.setDescription("Sample post");
        post.setComments(comments);

        // 构造外层包裹对象,对应预期的posts数组结构
        Map<String, List<Post>> result = new HashMap<>();
        result.put("posts", List.of(post));

        ObjectMapper objectMapper = new ObjectMapper();
        // 配置格式化规则
        DefaultPrettyPrinter printer = new DefaultPrettyPrinter();
        printer.indentArraysWith(new DefaultIndenter());

        // 直接序列化结果对象写入文件,不要二次序列化
        objectMapper.writer(printer).writeValue(new File("car.json"), result);
        // 如果需要拿到序列化后的字符串,直接用result转换即可
        String serialized = objectMapper.writer(printer).writeValueAsString(result);
        System.out.println(serialized);
    }
}

修改后输出的JSON就会和你期望的格式完全一致。

内容的提问来源于stack exchange,提问作者Csabatron99

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 17:15:03