草庐IT

@DateTimeFormat和@JsonFormat介绍

☜阳光 2024-06-29 原文

文章目录

1.@DateTimeFormat注解

1.1@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本质上是一个接口

@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
   }
}

1.2@DateTimeFormat注解的功能

@DateTimeFormat注解的功能是将一个日期字符串转化为对应的Date类型,主要处理前端时间类型与后端pojo对象中的成员变量进行数据绑定在注解属性patttern中所约束的时间格式并不会影响后端返回前端的时间类型数据格式。

DateTimeFormat接口的pattern属性:

pattern属性类型为String类型,用于格式化字段或方法参数的自定义模式。默认为空字符串,表示没有指定自定义模式字符串。

当然也可以使用自定义日期模式字符串,如yyyy-MM-dd HH:mm:ss

1.3@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属性的约束。

1.4@DateTimeFormat功能演示

1.4.1类型转换异常情况测试

  1. pojo层
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class User {
    private String username;
    private Date birthday;
}
  1. controller层
@Slf4j
@RestController
@RequestMapping("/datetimeFormatTest")
public class DatetimeFormatTest {

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

请求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

1.4.2接收url路径传参格式测试

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

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

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

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

1.4.3接收Form-Data数据格式测试

  1. pojo和controller都不变

  2. 用ApiFox进行接口测试,传输的数据格式为Form-Data类型

  3. 测试结果:

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

1.4.4接收JSON数据格式测试

​ 接受JSON数据格式时,在接收参数时,通过@RequestBody获取请求体中的内容(即JSON字符串),再通过JSON解析库(如Jackson、FatJosn)将JSON字符串转换为pojo对象

  1. pojo层不变
  2. 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;
    }
}
  1. 用ApiFox进行接口测试,传输的数据格式为JSON类型

  1. 测试结果:

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

  1. 使用JSON解析库Jackson进行解析JSON数据

  2. 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;
}
  1. 用ApiFox进行接口测试,传输的数据格式为JSON类型

  1. 测试结果

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

​ 这就引出了今天要介绍的另一个注解@JsonFormat

2.@JsonFormat注解

2.1@JsonFormat注解简介

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

所对应的依赖如下:

<!--Jackson包-->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>

​ SpringBoot的web依赖默认内置的有Jackson相应依赖。

2.2@JsonFormat注解的功能

@JsonFormat注解的功能是处理请求中的JSON日期字符串和查询数据库中的日期类型。即可约束时间类型的请求格式和响应格式。

JsonFormat接口的pattern属性:

pattern属性类型为String类型,用于格式化字段或方法参数的自定义模式。默认为空字符串,表示没有指定自定义模式字符串。

当然也可以使用自定义日期模式字符串,如yyyy-MM-dd HH:mm:ss

JsonFormat接口的timezone属性:

东八区([UTC]/[GMT]+08:00)是比[世界协调时间](UTC)/[格林尼治时间](GMT)快8小时的时区,我国就是属于东八区,所以要指定时区为"GMT+8"

2.3@JsonFormat注解的注意点

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

2.4@JsonFormat功能演示

2.4.1处理前端传递的日期字符串

  1. 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;
}
  1. 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;
    }
}
  1. 测试结果:

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

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

2.4.2处理查询数据库中的datatime类型格式

  1. 数据库中的数据格式为datatime类型

  1. 先测试不添加@JsonFormat注解时的情况,发送请求,查询数据库,查看响应的JSON数据

  1. 添加@JsonFormat注解再次进行测试

    ​ 数据格式转换成功

3.总结

  • 当处理的数据格式为非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);

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

有关@DateTimeFormat和@JsonFormat介绍的更多相关文章

  1. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  2. H2数据库配置及相关使用方式一站式介绍(极为详细并整理官方文档) - 2

    目录H2数据库入门以及实际开发时的使用1.H2数据库的初识1.1H2数据库介绍1.2为什么要使用嵌入式数据库?1.3嵌入式数据库对比1.3.1性能对比1.4技术选型思考2.H2数据库实战2.1H2数据库下载搭建以及部署2.1.1H2数据库的下载2.1.2数据库启动2.1.2.1windows系统可以在bin目录下执行h2.bat2.1.2.2同理可以通过cmd直接使用命令进行启动:2.1.2.3启动后控制台页面:2.1.3spring整合H2数据库2.1.3.1引入依赖文件2.1.4数据库通过file模式实际保存数据的位置2.2H2数据库操作2.2.1Mysql兼容模式2.2.2Mysql模式

  3. Spring Cloud Gateway 服务网关的部署与使用详细介绍 - 2

    为什么需要服务网关传统的单体架构中只需要开放一个服务给客户端调用,但是微服务架构中是将一个系统拆分成多个微服务,如果没有网关,客户端只能在本地记录每个微服务的调用地址,当需要调用的微服务数量很多时,它需要了解每个服务的接口,这个工作量很大。有了网关之后,网关作为系统的唯一流量入口,封装内部系统的架构,所有请求都先经过网关,由网关将请求路由到合适的微服务。使用网关的好处1)简化客户端的工作。网关将微服务封装起来后,客户端只需同网关交互,而不必调用各个不同服务;(2)降低函数间的耦合度。一旦服务接口修改,只需修改网关的路由策略,不必修改每个调用该函数的客户端,从而减少了程序间的耦合性(3)解放开发

  4. ruby - Vim 详细介绍了 Rails 的自动完成功能 - 2

    我发现python的细节自动完成很好RubyonRails有类似的方法描述吗? 最佳答案 有篇不错的文章"UsingVIMasacompleteRubyonRailsIDE"其中引用rails.vim.这似乎是RailsforVIM的实际标准。(不过,我还没有使用过它,但很快就会尝试。)这允许你做很多与Rails相关的任务,但对自动完成没有帮助。还有一篇"RubyAutocompleteinVim"(遗憾的是不再可用)这就是您要搜索的内容。我不知道,理解Rails的所有插件魔法和元编程的东西是否足够聪明。它至少在vim的配置中提到了

  5. 华为防火墙简单介绍 - 2

    防火墙防火墙分类第一代防火墙:包过滤防火墙包过滤防火墙的缺点第二代防火墙:代理防火墙第三代防火墙:状态防火墙第四代防火墙:UTM防火墙第五代防火墙:下一代防火墙华为防火墙介绍安全策略防火墙的会话表防火墙分类第一代防火墙:包过滤防火墙属于第一代防火墙技术,在没有专用防火墙设备时,一般由路由器实现该功能。将网络上传送数据包的IP首部以及TCP/UDP首部,获取发送源的IP地址和端口号,以及目的地的IP地址和端口号,并将这些信息作为过滤条件,决定是否将该分组转发至目的地网络分组过滤的执行需要设置访问控制列表。访问控制列表也可以称为安全策略(简称策略)或安全规则(简称规则)。类似于进站检票的做法,符合

  6. Qt样式表之 QSS 语法介绍;QLineEdit、 - 2

     内容来自Qt样式表之QSS语法介绍-3YL的博客Qt样式表是一个可以自定义部件外观的十分强大的机制,可以用来美化部件。Qt样式表的概念、术语和语法都受到了HTML的层叠样式表(CascadingStyleSheets, CSS教程)的启发,不过与CSS不同的是,Qt样式表应用于部件的世界。类型选择器QPushButton匹配QPushButton及其子类的实例ID选择器QPushButton#okButton匹配所有objectName为okButton的QPushButton实例。 CSS常用样式1CSS文字属性注:px:相对长度单位,像素(Pixel)。pt:绝对长度单位,点(Point

  7. Android对话框的详细介绍(提示对话框,自定义对话框) - 2

    简介:我们都知道在Android开发中,当我们的程序在与用户交互时,用户会得到一定的反馈,其中以对话框的形式的反馈还是比较常见的,接下来我们来介绍几种常见的对话框的基本使用。前置准备:(文章最后附有所有代码)我们首先先写一个简单的页面用于测试这几种Dialog(对话框)代码如下,比较简单,就不做解释了一、提示对话框(即最普通的对话框)首先我们给普通对话框的按钮设置一个点击事件,然后通过AlertDialog.Builder来构造一个对象,为什么不直接Dialog一个对象,是因为Dialog是一个基类,我们尽量要使用它的子类来进行实例化对象,在实例化对象的时候,需要将当前的上下文传过去,因为我这

  8. 技术分享 | observer 资源水位介绍 - 2

    作者:郭斌斌爱可生DBA团队成员,负责项目日常问题处理及公司平台问题排查。本文来源:原创投稿*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。OceanBase集群界面会展示Observer的资源水位,今天简单了解一下资源水位的数值代表的含义以及关联参数现有test_1集群,只有一个sys租户Sys租户的资源配置:Cpu:2.5-5Memory:3G-3GUnit:1集群的资源水位信息以10.186.63.198为例,浅看一下cpu、内存、磁盘的含义以及相关联参数cpu:2.5/17核2.5代表observer上已经分配给租户的cpu核数,该数值是租户的MinCPU

  9. (一)专题介绍:移动端安卓手机改造成linux服务器&linux服务器中安装软件、部署前后端分离项目实战 - 2

    快捷目录前言一、涉及到的相关技术简介二、具体实现过程及踩坑杂谈1.安卓手机改造成linux系统实现方案2.改造后的手机Linux中软件的安装3.手机Linux中安装MySQL5.7踩坑实录4.手机Linux中安装软件的正确方法三、Linux服务器部署前后端分离项目流程1.前提准备(安装必要软件,搭建环境):2.前后端分离项目的详细部署过程:总结前言总体概述:本篇文章隶属于“手机改造服务器部署前后端分离项目”系列专栏,该专栏将分多个板块,每个板块独立成篇来详细记录:手机(安卓)改造成个人服务器(Linux)、Linux中安装软件、配置开发环境、部署JAVA+VUE+MySQL5.7前后端分离项目

  10. 涡旋光束基本概念介绍 - 2

    涡旋光束及其MATLAB实现前言涡旋光束的基本概念常见的涡旋涡旋光束涡旋光束的产生方法前言笔者新开一块专栏,专门用于讨论整理总结涡旋光束的相关内容,从基本的概念出发,推导相关的公式,并结合MATLAB进行相关的仿真,不清楚这个专栏会更新多少期,我会分享部分的代码,全部的代码有需要的话可以私聊我。当然大家对这个专栏感兴趣的话,欢迎积极交流。涡旋光束的基本概念​涡旋光束(vortexbeam)是指携带光学涡旋,具有exp(imϕ)exp(im\phi)exp(imϕ)相位分布的光束,其中mmm表示相位拓扑电荷数,ϕ\phiϕ是柱坐标下的方位角。之前的分享中笔者已经说明了部分的激光光束的表达式,想要

随机推荐