使用Jackson将Java对象转JSON:提取tags与调整结构
嘿,刚好之前做过类似的Jackson序列化需求,给你捋几个实用的方案,应该能解决你的问题:
解决方案:Jackson定制Java对象转JSON格式
先确认下我理解的需求:你要把Obj类的实例序列化为JSON,只保留name、tags字段,同时把Obj里的ArrayList<Properties>转成JSON数组(或你需要的特定列表格式),对吧?
第一步:确保POJO符合Jackson序列化要求
Jackson序列化的核心要求很简单,踩过坑的人都懂:
- 所有需要序列化的POJO(
Properties和Obj)必须有无参构造器(Jackson需要通过它创建实例) - 需要序列化的字段必须有对应的getter方法(Jackson默认通过getter读取字段值)
给你一个标准的POJO示例,你可以对照调整自己的类:
import com.fasterxml.jackson.annotation.JsonInclude; import java.util.ArrayList; import java.util.List; // Properties POJO,用注解排除空值字段让JSON更干净 @JsonInclude(JsonInclude.Include.NON_NULL) public class Properties { private String key; private String value; // 必须要有无参构造器,Jackson序列化/反序列化都依赖它 public Properties() {} // 方便初始化的带参构造器(可选) public Properties(String key, String value) { this.key = key; this.value = value; } // 所有需要序列化的字段的getter(setter可选,序列化不需要,但反序列化需要的话要加) public String getKey() { return key; } public String getValue() { return value; } // 可选:setter方法 public void setKey(String key) { this.key = key; } public void setValue(String value) { this.value = value; } } // Obj类,同样排除空值字段 @JsonInclude(JsonInclude.Include.NON_NULL) public class Obj { private String name; private List<String> tags; private ArrayList<Properties> properties; // 无参构造器 public Obj() {} // 带参构造器(可选) public Obj(String name, List<String> tags, ArrayList<Properties> properties) { this.name = name; this.tags = tags; this.properties = properties; } // getter方法 public String getName() { return name; } public List<String> getTags() { return tags; } public ArrayList<Properties> getProperties() { return properties; } // 可选:setter方法 public void setName(String name) { this.name = name; } public void setTags(List<String> tags) { this.tags = tags; } public void setProperties(ArrayList<Properties> properties) { this.properties = properties; } }
第二步:基础序列化(输出符合要求的JSON)
用Jackson的ObjectMapper做序列化,只要POJO符合上面的要求,ArrayList<Properties>会自动被序列化为JSON数组,name和tags也会正常输出:
import com.fasterxml.jackson.databind.ObjectMapper; public class JacksonDemo { public static void main(String[] args) throws Exception { // 构造测试数据 ArrayList<Properties> props = new ArrayList<>(); props.add(new Properties("color", "red")); props.add(new Properties("size", "large")); List<String> tags = List.of("hot", "popular"); Obj product = new Obj("ProductA", tags, props); // 初始化ObjectMapper ObjectMapper mapper = new ObjectMapper(); // 美化输出JSON(可选,方便调试查看) String jsonResult = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(product); System.out.println(jsonResult); } }
运行后输出的JSON会是这样,完全符合你的需求:
{ "name" : "ProductA", "tags" : [ "hot", "popular" ], "properties" : [ { "key" : "color", "value" : "red" }, { "key" : "size", "value" : "large" } ] }
第三步:自定义调整(如果默认格式不符合预期)
如果你需要更定制化的格式,比如:
- 排除不需要的字段:给
Obj里不需要序列化的字段加@JsonIgnore注解public class Obj { private String name; private List<String> tags; private ArrayList<Properties> properties; @JsonIgnore // 这个字段不会出现在最终JSON里 private String internalId; // ... 其他代码 } - 自定义properties的格式:比如把
properties数组转成键值对对象,而不是对象数组,可以用自定义序列化器:
然后在import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import java.io.IOException; import java.util.ArrayList; public class PropertiesSerializer extends JsonSerializer<ArrayList<Properties>> { @Override public void serialize(ArrayList<Properties> props, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeStartObject(); for (Properties prop : props) { gen.writeStringField(prop.getKey(), prop.getValue()); } gen.writeEndObject(); } }Obj的properties字段上添加注解指定序列化器:
这样输出的import com.fasterxml.jackson.databind.annotation.JsonSerialize; public class Obj { // ... 其他字段 @JsonSerialize(using = PropertiesSerializer.class) private ArrayList<Properties> properties; // ... 其他代码 }properties会变成:"properties" : { "color" : "red", "size" : "large" }
关键注意点
- 一定要保留无参构造器,否则Jackson会直接抛出序列化异常
- 如果字段是
private的,必须提供getter方法,否则Jackson无法读取字段值 - 用
@JsonInclude(JsonInclude.Include.NON_NULL)可以自动排除null值的字段,让JSON更简洁
内容的提问来源于stack exchange,提问作者lrente
相关产品推荐
相关产品推荐

