tags: [jackson]
categories: [工具]
前言
这么多序列化工具,自己最喜欢的还是Jackson,关于它的学习一直是零零散散的学习,用到什么去找什么,现在在这里做个总结
依赖引入
<!--jackson--><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency><!-- <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId></dependency>-->
jackson-databind已经包含了jackson-core和jackson-annotations,所以我们引入一个就可以了
jackson-core,核心包,提供基于”流模式”解析的相关 API,它包括 JsonPaser 和 JsonGenerator。 Jackson 内部实现正是通过高性能的流模式 API 的 JsonGenerator 和 JsonParser 来生成和解析 jsonjackson-annotations,注解包,提供标准注解功能;jackson-databind,数据绑定包, 提供基于”对象绑定” 解析的相关 API ( ObjectMapper ) 和”树模型” 解析的相关 API (JsonNode);基于”对象绑定” 解析的 API 和”树模型”解析的 API 依赖基于”流模式”解析的 API。
Jackson使用
我们使用Jackson无非是为了序列化和反序列化,Jackson通常的序列化对象为ObjectMapper,我们可以通过配置该对象的属性来达到定制化序列化的效果,但是通常情况下,只需要简单的序列化即可
基本用法
1. 对象序列化和反序列化
private static final ObjectMapper MAPPER = new ObjectMapper();@SneakyThrowspublic static String toJson(Object object) {if (null == object) {return "";}return MAPPER.writeValueAsString(object);}@SneakyThrowspublic static <T> T parseJson(String json, Class<T> valueType) {return MAPPER.readValue(json, valueType);}
注意:
- 这里的序列化指的是简单对象,即对象中依然包含对象是不支持的,带泛型的List也是不支持
2. 注解使用
| 注解 | 用法 |
|---|---|
| @JsonProperty | 用于属性,把属性的名称序列化时转换为另外一个名称。示例: @JsonProperty(“birth_ d ate”) private Date birthDate; |
| @JsonFormat | 用于属性或者方法,把属性的格式序列化时转换成指定的格式。示例: @JsonFormat(timezone = “GMT+8”, pattern = “yyyy-MM-dd HH:mm”) public Date getBirthDate() |
| @JsonPropertyOrder | 用于类, 指定属性在序列化时 json 中的顺序 , 示例: @JsonPropertyOrder({ “birth_Date”, “name” }) public class Person |
| @JsonCreator | 用于构造方法,和 @JsonProperty 配合使用,适用有参数的构造方法。 示例: @JsonCreator public Person(@JsonProperty(“name”)String name) {…} |
| @JsonAnySetter | 用于属性或者方法,设置未反序列化的属性名和值作为键值存储到 map 中 @JsonAnySetter public void set(String key, Object value) { map.put(key, value); } |
| @JsonAnyGetter | 用于方法 ,获取所有未序列化的属性 public Map |
3. SprinBoot的序列化设置
我们知道Spingboot默认的序列化方式都是jackson,当然你也可以自己以其他比如FastJSON的方式去替换掉,这里只谈Jackson
- 很多时候SpringBoot对于前端参数解析,也就是序列化的时候,一些日期格式是不支持,比如旧版本的不支持
yyyy-MM-dd hh:mm:ss日期格式,这会导致麻烦的解析失败,耽误时间 - 回传数据给前端时,数据反序列化格式不统一,
LocalDateTime数据类型包含了一个T - Jackson默认时区为UTC,当发现操作系统时区为GMT+8时,会将原时间加上8小时返回,这个算个坑,踩过了就还好
关于第一个问题第三个问题可以在application.yml中配置
spring:jackson:time-zone: GMT+8date-format: 'yyyy-MM-dd HH:mm:ss'
也可以在项目中使用配置类配置,个人推荐使用第二种,尤其是在大型项目中,这块可以放到公用依赖中,方便复用
以下是通过配置类方式
@Configurationpublic class SpringJsonConfig {/*** 标准日期*/private static final String DATE_PATTERN = "yyyy-MM-dd";/*** 标准日期时间*/private static final String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";@Beanpublic Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() {return jacksonObjectMapperBuilder ->{jacksonObjectMapperBuilder.simpleDateFormat(DATE_PATTERN);jacksonObjectMapperBuilder.serializerByType(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DATE_PATTERN)));jacksonObjectMapperBuilder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DATE_TIME_PATTERN)));jacksonObjectMapperBuilder.timeZone(TimeZone.getTimeZone("GMT+8"));jacksonObjectMapperBuilder.serializationInclusion(JsonInclude.Include.NON_NULL);};}}
4. ObjectMapper的常用配置
对于ObjectMapper的配置,通常是在Json工具类中配置好来使用,最好可以配置上默认的设置,方便使用
//忽略不识别的字符串objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);//允许原始值为nullobjectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);//允许枚举转换为数字objectMapper.configure(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS, false);//序列化时null值自动忽略objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);//日期格式化模式objectMapper.setDateFormat(new SimpleDateFormat(DATE_PATTERN));
高阶用法
- 自定义序列化器
