Spring MVC日期序列化问题

Spring MVC日期序列化

1. 问题

Spring MVC默认会将LocalData,LocalDataTime,LocalTime序列化为ArrayList,将时间信息拆分后放到数组中,可能会出现反序列化错误

2. 示例

示例Spring MVC将LocalData,LocalDataTime,LocalTime序列化为什么内容

  • 序列化对象

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
      class UserDto {
    
            private String userName;
            private LocalDateTime birthday;
    
       }
    
  • 处理器,用于处理请求的

    请求会传入UserDTO对象,处理器返回UserDTO对象序列化后的Json字符串,通过它可以看到UserDTO中的类型为LocalDateTime的birthday字段会序列化为什么内容

    @RestController
    class HelloController {
    
         @PostMapping("/user")
         public UserDto user(@RequestBody UserDto userDto) throws Exception {
             return userDto;
         }
    
    }
    
  • 发送请求

      ![file](https://i-blog.csdnimg.cn/blog_migrate/64c3c7384b73402c68eb59849410c7f8.png)
    
  • 响应内容

    从响应内容可以看出,birthday被序列化为一个数组,由此可以证明Spring MVC默认将LocalDateTime序列化为数组

    file

3. 解决方案

  1. 使用@JsonFormat注解

    • 说明

      只需要在LocalDateTime字段上加上@JsonFormat注解,声明时间的字符串格式即可

    • 示例

      需要注意的时,请求时发送的字符串格式需要跟pattern声明的字符串格式保持一致

      @Data
      @NoArgsConstructor
      @AllArgsConstructor
      class UserDto {
      
        private String userName;
        @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")
        private LocalDateTime birthday;
          
      }
      
    • 结果

      此时Spring MVC序列化LocalDateTime类型的方式确实发生了变化

      file

  2. 定制序列化方式

    • 说明

      jackson也为此提供了一整套的序列化方案,我们只需要在pom.xml中引入jackson-datatype-jsr310依赖,然后在应用主类中增加这个序列化模块,并禁用对日期以时间戳方式输出的特性即可

    • 示例

      • maven引入依赖

        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
        </dependency
        
      • 添加序列化模块

         @Bean
         public ObjectMapper serializingObjectMapper() {
             ObjectMapper objectMapper = new ObjectMapper();
             //禁止将Date序列化为时间戳
             objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
             objectMapper.registerModule(new JavaTimeModule());//注册模块
             return objectMapper;
         }
        
    • 结果展示

      注意,此时字符串格式必须符合LocalDateTime的格式,为yyyy-MM-ddTHH:mm:ss,

      例如"2022-02-22T22:22:22",这样请求接收到参数才能正常转换

      • 请求

        请求是birthday的字符串格式必须是yyyy-MM-ddTHH:mm:ss格式

        file

      • 响应

        此时由于注册了JavaTimeModule序列化模块,Spring MVC序列化LocalDateTime类型的方式确实发生了变化

        file

4. 总结

Spring MVC默认会将LocalDate,LocalDateTime,LocalTime序列化为数组,在某些场景下会出错,所以需要修改Spring MVC默认的序列化方式,序列化结果从数组转换为表示时间的字符串。

​上面虽然只用了LocalDateTime来举例,但是对于LocalDate,LocalTime都是通用的。

参考文章: https://blog.didispace.com/Spring-Boot-And-Feign-Use-localdate/
https://www.cnblogs.com/codecat/p/10845797.html

本文由博客一文多发平台 OpenWrite 发布!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring MVC中,Controller的序列化和反序列化是通过使用注解来实现的。对于请求体的反序列化,可以使用 @RequestBody 注解来接收请求体。而对于响应体的序列化,可以使用 @ResponseBody 注解将返回值作为响应体。 具体来说,在Spring MVC中,使用 @RequestBody 注解标注的Controller方法参数可以用来接收请求体。而使用 @ResponseBody 注解标注的Controller方法则会将返回值作为响应体。请求体和响应体还可以具有不同的内容类型,比如json、xml等等。 在Spring MVC中,Controller方法参数的解析统一使用HandlerMethodArgumentResolver接口。该接口定义了两个方法:supportsParameter用于判断是否支持给定的方法参数,resolveArgument用于解析方法参数。 对于使用 @RequestBody 注解标注的参数,同样也是通过HandlerMethodArgumentResolver进行解析。 在具体实现中,RequestResponseBodyMethodProcessor是一个处理器,它负责将Controller方法返回值转换为响应体。其中,核心代码如下: ```java public class RequestResponseBodyMethodProcessor { // ... public void writeWithMessageConverters(Object returnValue, MethodParameter returnType, ServletServerHttpResponse response) throws IOException, HttpMediaTypeNotAcceptableException { // ... } // ... } ``` 总结起来,Spring MVC使用注解来实现Controller的序列化和反序列化。对于请求体的反序列化,可以使用 @RequestBody 注解标注参数;而对于响应体的序列化,可以使用 @ResponseBody 注解标注方法。具体的参数解析和返回值转换则是通过HandlerMethodArgumentResolver和RequestResponseBodyMethodProcessor来完的。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Spring MVC @RequestBody @ResponseBody 序列化序列化实现](https://blog.csdn.net/zzuhkp/article/details/122935899)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值