序列化反序列化常用设置
序列化和反序化的实用配置
Jackson-时间
序列化
- Date 序列化为时间戳
ObjectMapper objectMapper = new ObjectMapper(); objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true);
spring.jackson.serialization.write-dates-as-timestamps=true
- JDK8
objectMapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false );
spring.jackson.serialization.write-date-timestamps-as-nanoseconds=false
java.time.Instant
和java.time.ZonedDateTime
类型会序列化为 毫秒级时间戳
反序列化
- 毫秒级时间戳会顺利反序列化为
java.util.Date
- JDK8
//不把时间戳当成nanoseconds, 否则会把毫秒当成秒读
objectMapper.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS,false);
spring.jackson.deserialization.read-date-timestamps-as-nanoseconds=false
毫秒级时间戳会反序列化为 java.time.Instant
和 java.time.ZonedDateTime
指定
-
@JsonFormat
: 输出想要的格式-
@JsonFormat(pattern = ``"yyyy-MM-dd HH:mm:ss"``,timezone=``"GMT+8"``) @JsonFormat(without = JsonFormat.Feature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS) //同上序列化设置
-
-
@DateTimeFormat
:解析想要的格式
Jackson-枚举
objectMapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, true);
objectMapper.configure(SerializationFeature.WRITE_ENUMS_USING_INDEX, true);
spring.jackson.serialization.write-enums-using-index=true
spring.jackson.serialization.write-enums-using-to-string=true
- 确定序列化枚举时使用 ordinary 还是 string
- 反序列化时,无论使用ordinary 还是string 都能兼容并反序列化
Jackson-精度
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
@JsonSerialize(using = ToStringSerializer.class)
private BigDecimal sallary;
- 使用
ToStringSerializer.class
进行序列化 - 该注解可以用来对任意一个成员变量指定序列化类
Jackson-XML
部分老旧的接口任然在使用XML 序列化
依赖
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
使用注解调整格式
将字段作为标签属性或父元素属性
/**
* <name>xxx</name>
* ==>
* <element nm="xxx"></element>
*/
@JacksonXmlProperty(isAttribute = true, localName = "nm")
private String name;
设置最外层标签
/**
* <MyType>xxx</MyType>
* ==>
* <Hello xmlns="abcdefg"></Hello>
*/
@JacksonXmlRootElement(namespace = "abcdefg",localName = "Hello")
public class MyType {}
集合包装
/**
* JacksonXmlElementWrapper 时外层集合名称
* useWrapping = false 则会去掉外层大标签
*
* <AAA>
* <aaa></aaa>
* <aaa></aaa>
* </AAA>
*
*/
@JacksonXmlElementWrapper(localName = "AAA")
@JacksonXmlProperty(localName = "aaa")
private Collections<String> bbb;
直接暴露给父标签
/**
*<root><c>a</c></root>
* ==>
*<root></root>
*/
@JacksonXmlText;
private String c;
MyBatis-枚举
mybatis.configuration.default-enum-type-handler=org.apache.ibatis.type.EnumOrdinalTypeHandler
- 枚举类型会被序列化为Ordinal 存储
关于枚举使用的一点建议
- 虽然框架都提供了 使用 ordinal 反序列化的设置, 实际使用中会出现 几个问题
- 枚举的 ordinal 和 枚举的顺序有关, 会被代码格式等工具破坏
java.lang.Enum
默认不提供valueOf(int ordinal)
方法, 在三方框架不提供适配时, 使用成本高, 需要手动封装- 在提供给三方使用的SDK 或者jar 包里使用 枚举 更合适, 源代码不会被破坏