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类型数据的接收

  1. 编写工具类
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);
    }

}

  1. 在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
  1. 使用此注解时,Controller层中的参数前加@RequestParam或者不加注解使用
  2. @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
  1. @JsonFormat注解一般是在前端使用application/json 传递参数的时候生效,这时候在Date类型的字段上使用该注解,也能直接接收时间格式的字符串,并且转换成设置的格式。
  2. 一般是在SpringMvc的Controller层中JAVA类参数前加上@RequestBody使用,因为前端使用Content-Type是application/json 方式,所以要用@RequestBody来接收参数解析并且绑定。这时候反序列化用到的是Jackjson的反序列化,所以@JsonFormat注解生效。
  3. @JsonFormat注解一般只用在实体类的字段上。patten的属性表示时间字符串格式,timezone属性表示时区。
区别:
  1. @JsonFormat在处理Json格式的数据的时候,需要配套使用注解@RequestBody(前端的Context-type一般为application/json)

在这里参数的解析使用的是jackson的序列化以及反序列化,由于@JsonFormat注解的设置,在Json反序列化的时候,会把时间的String字符串转换成Date类型

  1. @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注解依然生效,会再序列化成指定的时间格式字符串。

posted @ 2020-09-29 17:39  玖捌贰陆  阅读(828)  评论(0编辑  收藏  举报