在 SpringBoot 中使用 spring.jackson.date-format 只会对 Date 类型进行格式化,而使用 @JsonFormat 和 @DataTimeFormat 只能针对单个属性进行格式化,比较麻烦,所以需要一个全局的格式化

1. 输入输出数据时格式化

  • 方法里使用的常量来自 hutool
  • Controller 里直接使用 LocalDateTime 接收参数时还需指定 @DateTimeFormat
@Configuration
public class JacksonConfig {

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer customizer() {

        return builder -> {
            builder.locale(Locale.CHINA);
            builder.timeZone(TimeZone.getTimeZone(ZoneId.systemDefault()));
            builder.simpleDateFormat(NORM_DATETIME_PATTERN);
            builder.modules(this.getJavaTimeModule());
        };
    }

    public static JavaTimeModule getJavaTimeModule() {
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(NORM_DATETIME_PATTERN)));
        javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(NORM_DATE_PATTERN)));
        javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(NORM_TIME_PATTERN)));
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(NORM_DATETIME_PATTERN)));
        javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(NORM_DATE_PATTERN)));
        javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(NORM_TIME_PATTERN)));
        return javaTimeModule;
    }
}

2. 对象转Json时格式化

@Slf4j
public class JSONUtil {

    private static final ObjectMapper objectMapper = new ObjectMapper();

    static {
        objectMapper.registerModule(JacksonConfig.getJavaTimeModule());
        // 设置 java.util.Date 时间类的序列化以及反序列化的格式
        objectMapper.setDateFormat(new SimpleDateFormat(NORM_DATETIME_PATTERN));
        // 包含所有字段
        objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
        // 在序列化一个空对象时时不抛出异常
        objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        // 忽略反序列化时在 json 字符串中存在, 但在 java 对象中不存在的属性
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    }
    
    public static <T> String toJson(T object) {
        try {
            return objectMapper.writeValueAsString(object);
        } catch (IOException e) {
            log.warn("Parse object to string error", e);
            return null;
        }
    }

    public static <T> String toPrettyJson(T object) {
        try {
            return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);
        } catch (IOException e) {
            log.warn("Parse object to string error", e);
            return null;
        }
    }

    public static <T> T fromJson(String str, Class<T> clazz) {
        try {
            return objectMapper.readValue(str, clazz);
        } catch (Exception e) {
            log.warn("Parse String to object error!", e);
            return null;
        }
    }

    public static <T> T fromJson(String json, TypeReference<T> typeReference) {
        try {
            return objectMapper.readValue(json, typeReference);
        } catch (Exception e) {
            log.warn("Parse String to object error", e);
            return null;
        }
    }
}

Q.E.D.


盛年不重来,一日难再晨。