@DateTimeFormat和@JsonFormat介绍

@DateTimeFormat和@JsonFormat介绍

@DateTimeFormat注解

@DateTimeFormat注解简介

  • @DateTimeFormat注解是由Spring提供的一个注解,位于Spring和核心组件之一的context组件。对应的所需依赖如下:

  • # SpringBoot对应的依赖
    	<dependency>
        	<groupId>org.springframework.boot</groupId>
        	<artifactId>spring-boot-starter-web</artifactId>
    	</dependency>
    
    # Spring对应的依赖
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
            </dependency>
    
  • 双击shift快捷键,全局搜索DateTimeFormat,查看外部库,DateTimeFormat本质上是一个接口

  • img

  • @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
    public @interface DateTimeFormat {
       String style() default "SS";
    
       ISO iso() default ISO.NONE;
    
       String pattern() default "";
    
       String[] fallbackPatterns() default {};
        
       enum ISO {
          DATE,
          TIME,
          DATE_TIME,
          NONE
       }
    }
    

@DateTimeFormat注解的功能

  • @DateTimeFormat注解的功能是将一个日期字符串转化为对应的Date类型,主要处理前端时间类型与后端pojo对象中的成员变量进行数据绑定,在注解属性patttern中所约束的时间格式并不会影响后端返回前端的时间类型数据格式。
  • DateTimeFormat接口的pattern属性:
  • pattern属性类型为String类型,用于格式化字段或方法参数的自定义模式。默认为空字符串,表示没有指定自定义模式字符串。当然也可以使用自定义日期模式字符串,如yyyy-MM-dd HH:mm:ss

@DateTimeFormat注解的注意点

  • @DateTimeFormat注解既可以作用于pojo类型的属性上,也可以作用于方法参数上。

  • 前端传入的时间类型的字符串要和pattern属性所规定的规则相同。

  • @DateTimeFormat注解只能处理非JSON数据格式的字符串(如url-String格式、Form-Data格式),如果要处理JSON数据格式,就需要采用@RequestBody注解,@RequestBody就是获取请求体中的内容(即JSON字符串),再通过JSON解析库(如Jackson、FatJosn)将JSON字符串转换为pojo对象。

  • 两种JSON解析库所需依赖:

  •         <!--       fastjson所需依赖 -->
    		<dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.54</version>
            </dependency>
    
  • Jackson由于是Spring提供的,所以它所需的依赖就在Spring依赖中。

  • @DateTimeFormat注解只是解析日期字符串转为Date类型,转换后的日期格式并不会受到@DateTimeFormat注解中pattern属性的约束。

@DateTimeFormat功能演示

类型转换异常情况测试
  • pojo层

  • @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @ToString
    public class User {
        private String username;
        private Date birthday;
    }
    
  • controller层

  • @Slf4j
    @RestController
    @RequestMapping("/datetimeFormatTest")
    public class DatetimeFormatTest {
    
        @GetMapping("/exception")
        public User dft1(User user){
          log.info( "用户信息是:" + user);
          return user;
        }
    }
    
  • 用ApiFox进行接口测试,传输的数据格式为url路径传参

  • img

  • 请求400,查看控制台日志信息

  • 报错信息:即String类型转换为Date类型失败

  • Failed to convert property value of type ‘java.lang.String’ to required type ‘java.util.Date’ for property ‘birthday’; nested exception is org.springframework.core.convert
    
接收url路径传参格式测试
  • pojo层

  • @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @ToString
    public class User {
        private String username;
        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private Date birthday;
    }
    
  • 用ApiFox进行接口测试,传输的数据格式为url路径传参

  • 查看响应情况和控制台输出情况:可以发现@DateTimeFormat注解对日期字符串进行了解析,转换为对应的Date类型

  • 但是要注意:@DateTimeFormat注解只是解析日期字符串转为Date类型,转换后的日期格式并不会受到@DateTimeFormat注解中pattern属性的约束。

  • img

  • 响应的JSON字符串数据如下:

  • image-20221101094616306

接收Form-Data数据格式测试
  • pojo和controller都不变
  • image-20221101100039452
  • 测试结果:
  • image-20221101100453834
  • 响应的JSON字符串数据如下:
  • image-20221101100026884
接收JSON数据格式测试
  • 接受JSON数据格式时,在接收参数时,通过@RequestBody获取请求体中的内容(即JSON字符串),再通过JSON解析库(如Jackson、FatJosn)将JSON字符串转换为pojo对象

  • pojo层不变

  • controller层

  • 通过FastJson处理JSON数据,fastjson默认使用的序列化格式就是: DEFFAULT_DATE_FORMAT = “yyyy-MM-dd HH:mm:ss”;

  • @Slf4j
    @RestController
    @RequestMapping("/datetimeFormatTest")
    public class DatetimeFormatTest {
        @GetMapping("/exception")
        public User dft1(@RequestBody String userMsg) {
            JSONObject jsonObject = new JSONObject();
            User user = JSONObject.parseObject(userMsg, User.class);
            log.info("用户信息是:" + user);
            return user;
        }
    }
    
  • 用ApiFox进行接口测试,传输的数据格式为JSON类型

  • image-20221101100403098

  • 响应的JSON字符串数据如下:

  • image-20221101134015537

  • 使用JSON解析库Jackson进行解析JSON数据

  • controller层

  • @GetMapping("/exception")
    public User dft1(@RequestBody String userMsg) {
        ObjectMapper objectMapper = new ObjectMapper();
        User user = null;
        try {
            user = objectMapper.readValue(userMsg, User.class);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        log.info("用户信息是:" + user);
        return user;
    }
    
  • 用ApiFox进行接口测试,传输的数据格式为JSON类型

  • image-20221101100403098

  • 测试结果

  • 控制台报错,错误信息提示反序列化失败,因为jackson默认的日期反序列不支持yyyy-MM-dd HH:mm:ss 这种格式,而是默认"yyyy-MM-dd’T’HH:mm:ss.SSSX",所以反序列化失败。

@JsonFormat注解

@JsonFormat注解简介

  • @JsonFormat注解是由Jackson提供的一个注解,位于Jackson的annotation包中,本身也是一个接口

  • image-20221101140321883

  • 所对应的依赖如下:

  • <!--Jackson包-->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>
    
  • SpringBoot的web依赖默认内置的有Jackson相应依赖。

  • image-20221101140228746

@JsonFormat注解的功能

  • @JsonFormat注解的功能是处理请求中的JSON日期字符串和查询数据库中的日期类型。即可约束时间类型的请求格式和响应格式。
  • JsonFormat接口的pattern属性:
  • pattern属性类型为String类型,用于格式化字段或方法参数的自定义模式。默认为空字符串,表示没有指定自定义模式字符串。当然也可以使用自定义日期模式字符串,如yyyy-MM-dd HH:mm:ss
  • JsonFormat接口的timezone属性:
  • 东八区([UTC]/[GMT]+08:00)是比[世界协调时间](UTC)/[格林尼治时间](GMT)快8小时的时区,我国就是属于东八区,所以要指定时区为"GMT+8"

@JsonFormat注解的注意点

  • @JsonFormat只能作用在实体类上,不能作用于方法参数上
  • @JsonFormat会根据pattrn属性约束日期格式,在返回数据时会返回约束日期格式,这点和@DateTimeFormat不同
  • @JsonFormat注解当需要处理前端传来的数据时,先通过@RequestBody将入参参数映射到实体后,@JsonFormat注解才能去对时间格式进行约束;

@JsonFormat功能演示

处理前端传递的日期字符串
  • pojo层

  • @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @ToString
    public class User {
        private String username;
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
        private Date birthday;
    }
    
  • controller层

  • @Slf4j
    @RestController
    @RequestMapping("/datetimeFormatTest")
    public class DatetimeFormatTest {
    
        @GetMapping("/exception")
        public User dft1(@RequestBody String userMsg) {
            ObjectMapper objectMapper = new ObjectMapper();
            User user = null;
            try {
                user = objectMapper.readValue(userMsg, User.class);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            log.info("用户信息是:" + user);
            return user;
        }
    }
    
  • 测试结果:

  • image-20221101144019882

  • 响应的JSON字符串数据如下:

  • 可以发现@JsonFormat注解可以根据pattern属性对返回的数据进行约束

  • image-20221101144945540

处理查询数据库中的datatime类型格式
  • 数据库中的数据格式为datatime类型
  • image-20221105184232640
  • 先测试不添加@JsonFormat注解时的情况,发送请求,查询数据库,查看响应的JSON数据
  • image-20221105184357348
  • image-20221105184450508
  • 添加@JsonFormat注解再次进行测试
  • 数据格式转换成功
  • image-20221105184553662

总结

  • 当处理的数据格式为非JSON格式(url路径传参、Form-Data)的时候适合使用@DateTimeFormat注解进行处理,就是格式化后的日期格式并不会按照属性pattern中所约束的格式响应,如果想要规定日期格式,可采用SimpleDateFormat对象进行处理。

  • SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String date = simpleDateFormat.format(user.getBirthday());
    System.out.println(date);
    
  • image-20221101151701854

  • 当处理的数据格式为JSON数据格式时适合使用@JsonFormat注解进行处理,如果是前端返回的JSON日期字符串,需要使用@RequestBody注解获取请求体中的JSON字符串,再通过JSON解析库将JSON字符串转换为对应的POJO类型。或者是从数据库中查出对应的DateTime类型时对类型进行转换。

  • 14
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT枫斗者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值