tags: [jackson]
categories: [工具]


前言

这么多序列化工具,自己最喜欢的还是Jackson,关于它的学习一直是零零散散的学习,用到什么去找什么,现在在这里做个总结

依赖引入

  1. <!--jackson-->
  2. <dependency>
  3. <groupId>com.fasterxml.jackson.core</groupId>
  4. <artifactId>jackson-databind</artifactId>
  5. </dependency>
  6. <!-- <dependency>
  7. <groupId>com.fasterxml.jackson.core</groupId>
  8. <artifactId>jackson-core</artifactId>
  9. </dependency>
  10. <dependency>
  11. <groupId>com.fasterxml.jackson.core</groupId>
  12. <artifactId>jackson-annotations</artifactId>
  13. </dependency>-->

jackson-databind已经包含了jackson-corejackson-annotations,所以我们引入一个就可以了

  • jackson-core,核心包,提供基于”流模式”解析的相关 API,它包括 JsonPaser 和 JsonGenerator。 Jackson 内部实现正是通过高性能的流模式 API 的 JsonGenerator 和 JsonParser 来生成和解析 json
  • jackson-annotations,注解包,提供标准注解功能;
  • jackson-databind ,数据绑定包, 提供基于”对象绑定” 解析的相关 API ( ObjectMapper ) 和”树模型” 解析的相关 API (JsonNode);基于”对象绑定” 解析的 API 和”树模型”解析的 API 依赖基于”流模式”解析的 API。

Jackson使用

我们使用Jackson无非是为了序列化和反序列化,Jackson通常的序列化对象为ObjectMapper,我们可以通过配置该对象的属性来达到定制化序列化的效果,但是通常情况下,只需要简单的序列化即可

基本用法

1. 对象序列化和反序列化

  1. private static final ObjectMapper MAPPER = new ObjectMapper();
  2. @SneakyThrows
  3. public static String toJson(Object object) {
  4. if (null == object) {
  5. return "";
  6. }
  7. return MAPPER.writeValueAsString(object);
  8. }
  9. @SneakyThrows
  10. public static <T> T parseJson(String json, Class<T> valueType) {
  11. return MAPPER.readValue(json, valueType);
  12. }

注意

  1. 这里的序列化指的是简单对象,即对象中依然包含对象是不支持的,带泛型的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 any() { return map; }

3. SprinBoot的序列化设置

我们知道Spingboot默认的序列化方式都是jackson,当然你也可以自己以其他比如FastJSON的方式去替换掉,这里只谈Jackson

  1. 很多时候SpringBoot对于前端参数解析,也就是序列化的时候,一些日期格式是不支持,比如旧版本的不支持yyyy-MM-dd hh:mm:ss日期格式,这会导致麻烦的解析失败,耽误时间
  2. 回传数据给前端时,数据反序列化格式不统一,LocalDateTime数据类型包含了一个T
  3. Jackson默认时区为UTC,当发现操作系统时区为GMT+8时,会将原时间加上8小时返回,这个算个坑,踩过了就还好

关于第一个问题第三个问题可以在application.yml中配置

  1. spring:
  2. jackson:
  3. time-zone: GMT+8
  4. date-format: 'yyyy-MM-dd HH:mm:ss'

也可以在项目中使用配置类配置,个人推荐使用第二种,尤其是在大型项目中,这块可以放到公用依赖中,方便复用
以下是通过配置类方式

  1. @Configuration
  2. public class SpringJsonConfig {
  3. /**
  4. * 标准日期
  5. */
  6. private static final String DATE_PATTERN = "yyyy-MM-dd";
  7. /**
  8. * 标准日期时间
  9. */
  10. private static final String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
  11. @Bean
  12. public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() {
  13. return jacksonObjectMapperBuilder ->{
  14. jacksonObjectMapperBuilder.simpleDateFormat(DATE_PATTERN);
  15. jacksonObjectMapperBuilder.serializerByType(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DATE_PATTERN)));
  16. jacksonObjectMapperBuilder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DATE_TIME_PATTERN)));
  17. jacksonObjectMapperBuilder.timeZone(TimeZone.getTimeZone("GMT+8"));
  18. jacksonObjectMapperBuilder.serializationInclusion(JsonInclude.Include.NON_NULL);
  19. };
  20. }
  21. }

4. ObjectMapper的常用配置

对于ObjectMapper的配置,通常是在Json工具类中配置好来使用,最好可以配置上默认的设置,方便使用

  1. //忽略不识别的字符串
  2. objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
  3. //允许原始值为null
  4. objectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
  5. //允许枚举转换为数字
  6. objectMapper.configure(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS, false);
  7. //序列化时null值自动忽略
  8. objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
  9. //日期格式化模式
  10. objectMapper.setDateFormat(new SimpleDateFormat(DATE_PATTERN));

高阶用法

  1. 自定义序列化器

相关