Jackson详解
简述
Jackson是springboot默认使用的一个Json序列化和反序列化的库,非常流行且高效,API设计灵活容易扩展和定制化。
ObjectMapper
ObjectMapper作为Jackson的门户,他是基于对象绑定的API。可以通过ObjectMapper把json串反序列化为java类,也可以将java类序列化为json串。
下面的例子我们以User类作为实例
@Data @NoArgsConstructor @AllArgsConstructor public class User { private Integer id; private String username; private Integer age; }
把json串反序列化为对象
我们可以使用ObjectMapper的readValue()方法,参数是json串和我们想要反序列化成的类
objectMapper.readValue(str, Student.class);// str是json字符串
如果想反序列化成特殊类型,可以使用下面的方法
objectMapper.readValue(str, Student[].class);// 数组 objectMapper.readValue(str, new TypeReference<List<Student>>() {});// list objectMapper.readValue(str, new TypeReference<Map<String,String>>() {});// map
把对象序列化为json串
我们可以使用ObjectMapper的writeValueAsString()方法,参数我们想序列化的类
objectMapper.writeValueAsString(student);
Jackson常用注解
@JsonIgnoreProperties
当json属性比java类中的属性多的时候,我们可以使用@JsonIgnoreProperties注解标注在类上,value里填写哪些属性需要忽略
或者标注@JsonIgnoreProperties(ignoreUnknown = true)表示忽略所有不认识的属性
@Data @NoArgsConstructor @AllArgsConstructor @JsonIgnoreProperties({"address"}) public class User { private Integer id; private String username; private Integer age; }
@JsonIgnore
当json属性比java类中的属性少的时候,我们可以使用@JsonIgnore注解标注在属性上,表示忽略该属性
@Data @NoArgsConstructor @AllArgsConstructor public class User { private Integer id; private String username; @JsonIgnore private Integer age; }
或使用@JsonIgnoreType标注在类上,表示忽略整个类的多余属性
@JsonProperty
@JsonProperty注解用于解决json属性名和java属性名不一致的情况,在属性上进行标注,value表示json的属性名
@Data @NoArgsConstructor @AllArgsConstructor public class User { private Integer id; private String username; @JsonProperty("userAge") private Integer age; }
@JsonUnwrapped
@JsonUnwrapped注解表示该属性以扁平的数据结构序列化或反序列化
例如我们的User类中的name属性是一个类,包含firstName和lastName
public class Name { private String firstName; private String lastName; }
如果我们想在User类序列号的时候将这个name摊平\扁平地显示,我们需要在name上标注@JsonUnwrapped
@Data @NoArgsConstructor @AllArgsConstructor public class User { private Integer id; @JsonUnwrapped private Name username; private Integer age; }
@JsonValue
@JsonValue注解一个类只能有一个,标注在属性上,表示json序列化的时候只序列化这一个值
像这样Student类序列化的时候就只会序列化name这一个属性
@Data @NoArgsConstructor @AllArgsConstructor public class Student { @JsonValue private String name; private Integer age; }
也可以标注在方法上,表示该方法的返回值会成为这个类的序列化结果
像这样Student的序列化结果就会只有一个result,如果返回值是类的话会Student类的序列化结果就是返回值这个类的序列化结果
@Data @NoArgsConstructor @AllArgsConstructor public class Student { private String name; private Integer age; @JsonValue public String getJsonValue(){ return "result"; } }
@JsonFormat
@JsonFormat注解标注在属性上,用于指定时间的序列化和反序列化结果格式
例如这样指定类Date类的pattern和时区
@Data @NoArgsConstructor @AllArgsConstructor public class Student { private String name; private Integer age; @JsonFormat(pattern="yyyy-MM-dd",timezone="GMT+8") private Date time; }
@JsonInclude
@JsonInclude注解标注在属性上,他会告诉jackson这个属性满足什么条件的时候才会被序列化
像这样表示username属性不为空的时候才会参与序列化
@Data @NoArgsConstructor @AllArgsConstructor public class User { private Integer id; @JsonInclude(Include.NON_NULL) private Name username; private Integer age; }
常用的还有NON_EMPTY和NON_DEFAULT
自定义序列化器和反序列化器
以上是Jackson提供的帮助我们定制序列化 / 反序列化的注解
如果我们需要更加客制化地进行序列化和反序列化,我们可以自定义我们的序列化器和反序列化器
如果现在我们需要序列化Student类,其中的time属性我们希望通过毫秒值进行序列化
我们要在time属性上标注@JsonSerialize,并指定我们自定义的序列化器
@Data @NoArgsConstructor @AllArgsConstructor public class Student { private String name; private Integer age; @JsonSerialize(using = DateSerializer.class) private Date time; }
然后我们创建DateSerializer类,这是我们自定义的序列化器,然后继承标准的序列化器,重写serialize方法
其中value就是当前需要序列化的类,我们使用gen的writeNumber方法输出我们的序列化结果
public class DateSerializer extends StdSerializer<Date> { protected DateSerializer() { super(Date.class); } @Override public void serialize(Date value, JsonGenerator gen, SerializerProvider provider) throws IOException { long epochMilli = value.getTime(); gen.writeNumber(epochMilli); } }
反序列化也是同理的,return的结果就是反序列化的结果
public class DateDeserializer extends StdDeserializer<Date> { protected DateDeserializer() { super(Date.class); } @Override public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { long epochMilli = p.getLongValue(); return new Date(epochMilli); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!