SpringMVC接受Date类型数据
https://blog.csdn.net/weixin_43606226/article/details/106553116
https://blog.csdn.net/weixin_43606226/article/details/106572109
https://blog.csdn.net/qq_28556245/article/details/76071913
Content-Type:
https://www.jianshu.com/p/de5845b4c095
参考了以上三篇博文
自定义转换函数,实现全局model或bean中date类型数据的接收
- 编写工具类
package com.ychs.util;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.beans.PropertyEditorSupport;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Description: 921SpringMVC
* Copyright: Copyright (c) 2020
* Company: 英才汇硕信息技术有限公司
*
* @author caoning <br>
* @version 1.0 <br>
* @created 2020/9/29
*/
public class SpecialDateEditor extends PropertyEditorSupport {
private Logger logger = LogManager.getLogger(this.getClass());
@Override
public void setAsText(String text) throws IllegalArgumentException {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = null;
try {
//防止空数据出错
if (text != null && !text.equals("")) {
date = format.parse(text);
}
} catch (ParseException e) {
format = new SimpleDateFormat("yyyy-MM-dd HH");
try {
date = format.parse(text);
} catch (ParseException e1) {
format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
try {
date = format.parse(text);
} catch (ParseException e2) {
format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
date = format.parse(text);
} catch (ParseException e3) {
format = new SimpleDateFormat("yyyy-MM-dd");
try {
date = format.parse(text);
} catch (ParseException e4) {
format = new SimpleDateFormat("yyyy-MM");
try {
date = format.parse(text);
} catch (Exception e5) {
logger.error("自动绑定日期数据出错", e);
}
}
}
}
}
}
setValue(date);
}
}
- 在BaseController中添加方法:
@Controller
public class BaseController {
protected Logger logger = LogManager.getLogger(this.getClass());
@InitBinder
public void initBinder(ServletRequestDataBinder binder) {
//自动转换日期类型的字段格式
binder.registerCustomEditor(Date.class, new SpecialDateEditor());
}
}
使用@DateTimeFormat注解
在bean中字段名前加上@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss"),表明可以接受这种日期格式的数据,
@DateTimeFormat(pattern="yyyy-MM-dd hh:mm:ss")
private Date classDate;
以上是在添加时用到的,
使用@JsonFormat注解
@JsonFormat(pattern="yyyy-MM-dd hh:mm:ss")
private Date classDate;
注意:在参考第一篇博文时,一定要注意看注意事项,
使用方法1和3时,前端传递的Content-type必须为x-www-form-urlencoded或者是表单提交或者是GET方式请求。使用方法2时,必须为POST,且Content-type为application/json。
使用@JsonFormat注解时Content-type必须为
application/json
,虽然他说使用此注解必须为POST,而我们向后台传输局一般也为post形式,但是还有类型的限制如果使用@JsonFormat注解会无法转换,没有使用
@JsonFormat与@DateTimeFormat
@DateTimeFoamat
- 使用此注解时,Controller层中的参数前加@RequestParam或者不加注解使用
- @DateTimeFormat 一般用在实体类的字段上,或者是Controller方法中的某个Date类型的参数前直接加。一般使用patten属性,表示接受的时间字符串格式
下面是在Controller中加注解的的实例:
Controller中:
@RequestMapping("/test")
public String test(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")Date time1
, @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd")Date time2) {
logger.info("time1 = " + time1);
logger.info("time2 = " + time2);
return "";
}
请求中:
idea控制台:
注: 后台注解时必须和前端type类型一致,否则会报错不加注解和格式错误都会报错!!!
@JsonFormat
- @JsonFormat注解一般是在前端使用application/json 传递参数的时候生效,这时候在Date类型的字段上使用该注解,也能直接接收时间格式的字符串,并且转换成设置的格式。
- 一般是在SpringMvc的Controller层中JAVA类参数前加上@RequestBody使用,因为前端使用Content-Type是application/json 方式,所以要用@RequestBody来接收参数解析并且绑定。这时候反序列化用到的是Jackjson的反序列化,所以@JsonFormat注解生效。
- @JsonFormat注解一般只用在实体类的字段上。patten的属性表示时间字符串格式,timezone属性表示时区。
区别:
- @JsonFormat在处理Json格式的数据的时候,需要配套使用注解@RequestBody(前端的Context-type一般为application/json)
在这里参数的解析使用的是jackson的序列化以及反序列化,由于@JsonFormat注解的设置,在Json反序列化的时候,会把时间的String字符串转换成Date类型
- @DateTimeFormat生效情况: 再不处理Json格式的字符串或者加注解@RequestParam或者不加注解的时候
注:@JsonFormat用来返回给前端的,@DateTimeFormat用来从前端接收Date的。这是不正确的
@JsonFormat也能从前端接收Date,只是需要前端传递JSON格式的数据,并且Content-Type需要为application/json,让SpringMVC辨识数据为JSON格式,从而让SpringMVC走jackson的序列化和反序列化
Content-Type:
web开发中服务端一般能自动设置准确的Content-Type,
如果在spring项目里使用@ResponseBody,spring会将响应的Content-Type设置为application/json;charset=UTF-8;
拓展: 在SpringMvc中,返回数据的时候,一般都是对象或者其他Map,List类型的数据,这时候
SpringMvc的HttpMessageConvert会自动转换成Json格式的数据输出,所以这时候JSON的序列化配置会生效,因此@JsonFormat注解依然生效,会再序列化成指定的时间格式字符串。