springboot 序列化反序列化中,Date与Long类型转化问题

一、response body 序列化Date与Long为String

方法1-配置 ResponseBody 中 Date 序列化

在application.yml中增加如下配置:
spring:
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
注意:该方法只针对于 springboo t默认的 jackson 序列化才有效,并且该方法只能配置日期相关

方法2-自定义序列化ObjectMap

@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
    for (HttpMessageConverter httpMessageConverter : converters){
        if(httpMessageConverter instanceof MappingJackson2HttpMessageConverter){
            ((MappingJackson2HttpMessageConverter) httpMessageConverter).setObjectMapper(new JacksonMapper());
        }
    }
}
}

public class JacksonMapper extends ObjectMapper {
    public JacksonMapper() {
        super();
        this.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
        this.configure(JsonGenerator.Feature.IGNORE_UNKNOWN, true);
        this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // null 值属性也序列化
        this.setSerializationInclusion(JsonInclude.Include.ALWAYS);
        // Long 值转string,解决前端因 Long 值太大而损失精度问题
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        simpleModule.addSerializer(long.class, ToStringSerializer.instance);
        //设置日期格式
        SimpleDateFormat smt = new SimpleDateFormat("yyyy-MM-dd");
        setDateFormat(smt);
        registerModule(simpleModule);
    }
}

注意:该方法只针对于 springboo t默认的 jackson 序列化才有效,并且会覆盖方法一中的配置

方法三-注册MappingJackson2HttpMessageConverter对象

@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
    return new MappingJackson2HttpMessageConverter(new JacksonMapper());
}

JacksonMapper 类同方法二

注意:该方法只针对于 springboo t默认的 jackson 序列化才有效,并且会覆盖方法一中的配置

说明:方法二与方法三是在org.springframework.http.converter.HttpMessageConverter层面,重构ObjectMap对象的方式

方法四-注册org.springframework.boot.autoconfigure.http.HttpMessageConverters对象

@Bean
public HttpMessageConverters useConverters() {
    // 1.需要定义一个convert转换消息的对象;
    FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
    // 2:添加fastJson的配置信息;
    FastJsonConfig fastJsonConfig = new FastJsonConfig();
    fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat,
    SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteMapNullValue);
    fastJsonConfig.setDateFormat("yyyy-mm-dd");
    SerializeConfig serializeConfig = SerializeConfig.globalInstance;
    serializeConfig.put(Long.class , ToStringSerializer.instance);
    serializeConfig.put(Long.TYPE , ToStringSerializer.instance);
    fastJsonConfig.setSerializeConfig(serializeConfig);
    // 3处理中文乱码问题
    List<MediaType> fastMediaTypes = new ArrayList<>();
    fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
    // 4.在convert中添加配置信息.
    fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);
    fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
    HttpMessageConverter<?> converter = fastJsonHttpMessageConverter;
    return new HttpMessageConverters(converter);
}

注意:该方法是替换 springboot 默认的 jackson 序列化方式,采用 fastjson 方式序列化

说明:方法二三四是在不同的层面解决序列化问题,不同的序列化方式都可以在这两个层面着手解决序列化问题,在这里我就不一一写明,大家举一反三即可。

二、RequestMapping 时,将前端字符串格式的Date参数反序列化解析

该问题解决只需要实现org.springframework.core.convert.converter.Converter接口即可

@Slf4j
@Component
public class DateConverter implements Converter<String, Date> {
      @Override
      public Date convert(String source) {
          if (StringUtils.isBlank(source)) { 
              return null;
          }
          if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$")) {
              return parseDate(source.trim(), "yyyy-MM-dd");
          }
          if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")) {
              return parseDate(source.trim(), "yyyy-MM-dd HH:mm:ss");
          }
          throw new IllegalArgumentException("Invalid value '" + source + "'");
      }
    
      public Date parseDate(String dateStr, String format) {
          Date date = null;
          try { 
              date = new SimpleDateFormat(format).parse(dateStr);
          } catch (ParseException e) { 
              log.warn("转换{}为日期(pattern={})错误!", dateStr, format);
          }
          return date;
      }
}

注意:Converter接口中泛型前一个是指原类型,后一个是目标类型

说明:同理,其他类型的转化也是时间该接口即可,大家举一反三

在使用 Feign 进行远程调用时,如果需要传递 Date 类型的参数,可以使用 Java 自带的日期时间 API,例如 java.util.Date 或者 java.time.LocalDateTime。但是,Feign 默认使用的是 Jackson 库进行序列化反序列化,而 Jackson 库对于 Date 类型的处理需要进行配置。 在使用 Feign 远程调用时,可以通过添加如下配置,来解决 Date 类型序列化问题: 1. 首先,在 pom.xml 添加以下依赖: ```xml <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> </dependency> ``` 2. 在使用 Feign 远程调用的接口,添加 @Configuration 注解,并定义一个 Feign 配置类: ```java @Configuration public class FeignConfig { @Bean public Encoder feignEncoder() { return new JacksonEncoder( new ObjectMapper() .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) .registerModule(new JavaTimeModule())); } @Bean public Decoder feignDecoder() { return new JacksonDecoder( new ObjectMapper() .disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE) .registerModule(new JavaTimeModule())); } } ``` 在上面的代码,我们配置了 Feign 的 Encoder 和 Decoder,使用 Jackson 库进行序列化反序列化,并且注册了 JavaTimeModule 模块,以支持 Java 8 的日期时间 API。 3. 在需要传递 Date 类型参数的 Feign 接口方法上,添加 @RequestParam 注解,并指定日期时间格式: ```java @RequestLine("GET /api/user") User getUser(@RequestParam("id") long id, @RequestParam("date") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date date); ``` 在上面的代码,我们使用 @DateTimeFormat 注解来指定 Date 类型参数的日期时间格式。 通过以上配置,我们就可以在 Feign 远程调用,传递 Date 类型的参数了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值