关于Springboot日期时间格式化处理方式总结

2020-03-04 12:03:52于丽

总结:

支持(content-type=application/json)请求中格式为yyyy-MM-dd HH:mm:ss的字符串,后台用@RequestBody接收,及返回值Date转为yyyy-MM-dd HH:mm:ss格式String; 支持java8日期api; 不支持(content-type=application/json)请求中yyyy-MM-dd等类型的字符串转为Date;

以上两种方式为JSON入参的全局化处理,推荐使用方式二,尤其适合大型项目在基础包中全局设置。

JSON入参及返回值局部差异化处理

场景: 假如全局日期时间处理格式为:yyyy-MM-dd HH:mm:ss,但是某个字段要求接收或返回日期yyyy-MM-dd。

方式一

使用springboot自带的注解@JsonFormat(pattern = "yyyy-MM-dd"),如下所示:

@JsonFormat(pattern = "yyyy-MM-dd", timezone="GMT+8")
private Date releaseDate;

点评: springboot默认提供,功能强大,满足常见场景使用,并可指定时区。

方式二

自定义日期序列化与反序列化,如下所示:

/**
 * 日期序列化
 */
public class DateJsonSerializer extends JsonSerializer<Date> {
  @Override
  public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws
      IOException {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    jsonGenerator.writeString(dateFormat.format(date));
  }
}

/**
 * 日期反序列化
 */
public class DateJsonDeserializer extends JsonDeserializer<Date> {

  @Override
  public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
    try {
      SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
      return dateFormat.parse(jsonParser.getText());
    } catch (ParseException e) {
      throw new RuntimeException(e);
    }
  }
}

/**
 * 使用方式
 */
@JsonSerialize(using = DateJsonSerializer.class)
@JsonDeserialize(using = DateJsonDeserializer.class)
private Date releaseDate;

日期时间格式化处理方式完整配置

@Configuration
public class DateHandlerConfig {

  /** 默认日期时间格式 */
  public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
  /** 默认日期格式 */
  public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
  /** 默认时间格式 */
  public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";

  /**
   * LocalDate转换器,用于转换RequestParam和PathVariable参数
   */
  @Bean
  public Converter<String, LocalDate> localDateConverter() {
    return new Converter<>() {
      @Override
      public LocalDate convert(String source) {
        return LocalDate.parse(source, DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT));
      }
    };
  }

  /**
   * LocalDateTime转换器,用于转换RequestParam和PathVariable参数
   */
  @Bean
  public Converter<String, LocalDateTime> localDateTimeConverter() {
    return new Converter<>() {
      @Override
      public LocalDateTime convert(String source) {
        return LocalDateTime.parse(source, DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT));
      }
    };
  }

  /**
   * LocalTime转换器,用于转换RequestParam和PathVariable参数
   */
  @Bean
  public Converter<String, LocalTime> localTimeConverter() {
    return new Converter<>() {
      @Override
      public LocalTime convert(String source) {
        return LocalTime.parse(source, DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT));
      }
    };
  }

  /**
   * Date转换器,用于转换RequestParam和PathVariable参数
   */
  @Bean
  public Converter<String, Date> dateConverter() {
    return new Converter<>() {
      @Override
      public Date convert(String source) {
        SimpleDateFormat format = new SimpleDateFormat(DEFAULT_DATE_TIME_FORMAT);
        try {
          return format.parse(source);
        } catch (ParseException e) {
          throw new RuntimeException(e);
        }
      }
    };
  }


  /**
   * Json序列化和反序列化转换器,用于转换Post请求体中的json以及将我们的对象序列化为返回响应的json
   */
  @Bean
  public ObjectMapper objectMapper(){
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    objectMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);

    //LocalDateTime系列序列化和反序列化模块,继承自jsr310,我们在这里修改了日期格式
    JavaTimeModule javaTimeModule = new JavaTimeModule();
    javaTimeModule.addSerializer(LocalDateTime.class,new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
    javaTimeModule.addSerializer(LocalDate.class,new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)));
    javaTimeModule.addSerializer(LocalTime.class,new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
    javaTimeModule.addDeserializer(LocalDateTime.class,new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
    javaTimeModule.addDeserializer(LocalDate.class,new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)));
    javaTimeModule.addDeserializer(LocalTime.class,new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));


    //Date序列化和反序列化
    javaTimeModule.addSerializer(Date.class, new JsonSerializer<>() {
      @Override
      public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        SimpleDateFormat formatter = new SimpleDateFormat(DEFAULT_DATE_TIME_FORMAT);
        String formattedDate = formatter.format(date);
        jsonGenerator.writeString(formattedDate);
      }
    });
    javaTimeModule.addDeserializer(Date.class, new JsonDeserializer<>() {
      @Override
      public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        SimpleDateFormat format = new SimpleDateFormat(DEFAULT_DATE_TIME_FORMAT);
        String date = jsonParser.getText();
        try {
          return format.parse(date);
        } catch (ParseException e) {
          throw new RuntimeException(e);
        }
      }
    });

    objectMapper.registerModule(javaTimeModule);
    return objectMapper;
  }
}