springboot接收Date类型数据异常与解决办法

栏目: Java · 发布时间: 5年前

内容简介:在默认情况下,不加任何有关接收Date类型数据的配置时,前端传递Date类型数据至后端接口,控制台出现以下异常:也就是说,在第一种情况,仅需要对某个Bean类的Date类型字段进行转换,那么只需要在Bean类属性上增加

在默认情况下,不加任何有关接收Date类型数据的配置时,前端传递Date类型数据至后端接口,控制台出现以下异常:

Failed to convert from type [java.lang.String] to type [java.util.Date] for value
 '2333333333'; nested exception is java.lang.IllegalArgumentException]]
复制代码

也就是说,在 SpringBoot 中,必须添加某种配置才能让前端正确传递时间类型数据到后端。下面针对不同的情况来介绍一下解决办法。

局部配置——使用 @DateTimeFormat

第一种情况,仅需要对某个Bean类的Date类型字段进行转换,那么只需要在Bean类属性上增加 @DateTimeFormat() 注解,括号内 pattern 为前端传递的日期格式。比如:

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
Date createTime;
复制代码

特点--缺陷:

按照如上配置,只能处理形如: 2018-11-2 2:22:2 这样固定格式的数据,无法处理时间戳和 2018-11-2 格式的数据。如果想要处理 2018-11-2 这样的时间,就必须把 pattern 改成 yyyy-MM-dd

可以对不同的属性赋予不同的 pattern ,但是对每个Date类型都要加上注解显得比较繁琐,也无法处理单个属性可能对应不同格式的值的情况。

更通用、有效的方式是定义一个时间转换类,并将其应用到所有的接口上。

全局配置——自定义时间转换器

分为两个步骤:

  • 编写一个时间转换类,把可能的格式转换为Date类型
  • 通过某种方式,将时间转换应用到Spring的所有接口上

时间转换类

import org.springframework.core.convert.converter.Converter;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 日期转换类
 * 将标准日期、标准日期时间、时间戳转换成Date类型
 */
public class DateConverter implements Converter<String, Date> {
    private static final String dateFormat = "yyyy-MM-dd HH:mm:ss";
    private static final String shortDateFormat = "yyyy-MM-dd";
    private static final String timeStampFormat = "^\\d+$";

    @Override
    public Date convert(String value) {

        if(StringUtils.isEmpty(value)) {
            return null;
        }

        value = value.trim();

        try {
            if (value.contains("-")) {
                SimpleDateFormat formatter;
                if (value.contains(":")) {
                    formatter = new SimpleDateFormat(dateFormat);
                } else {
                    formatter = new SimpleDateFormat(shortDateFormat);
                }
                return formatter.parse(value);
            } else if (value.matches(timeStampFormat)) {
                Long lDate = new Long(value);
                return new Date(lDate);
            }
        } catch (Exception e) {
            throw new RuntimeException(String.format("parser %s to Date fail", value));
        }
        throw new RuntimeException(String.format("parser %s to Date fail", value));
    }
}
复制代码

将时间转换类应用到接口上

介绍两种方式:使用 @Component + @PostConstruct@ControllerAdvice + @InitBinder

第一种方式:

@Component + @PostConstruct

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;

import javax.annotation.PostConstruct;

/**
 * @author zfh
 * @version 1.0
 * @date 2018/12/30 10:16
 */
@Component
public class WebConfigBeans {

  @Autowired
  private RequestMappingHandlerAdapter handlerAdapter;

  @PostConstruct
  public void initEditableAvlidation() {

    ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer)handlerAdapter.getWebBindingInitializer();
    if(initializer.getConversionService()!=null) {
      GenericConversionService genericConversionService = (GenericConversionService)initializer.getConversionService();

      genericConversionService.addConverter(new DateConverterConfig());

    }
  }
}
复制代码

第二种方式:

@ControllerAdvice + @InitBinder

有关这两个注解的含义请参考我的博客: Spring进阶之@ControllerAdvice与统一异常处理

import com.aegis.config.converter.DateConverter;
import com.aegis.model.bean.common.JsonResult;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;

/**
 * @author zfh
 * @version 1.0
 * @since 2019/1/4 15:23
 */
@ControllerAdvice
public class ControllerHandler {

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        GenericConversionService genericConversionService = (GenericConversionService) binder.getConversionService();
        if (genericConversionService != null) {
            genericConversionService.addConverter(new DateConverter());
        }
    }
}
复制代码

OK,关于SpringBoot处理前端日期传值的问题的相关解决办法就介绍到这里了。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

运营之光

运营之光

黄有璨 / 电子工业出版社 / 2016-9-1 / 59.00元

在互联网行业内,“运营”这个职能发展到一定阶段后,往往更需要有成熟的知识体系和工作方法来给予行业从业者们以指引。 《运营之光:我的互联网运营方法论与自白》尤其难得之处在于:它既对“什么是运营”这样的概念认知类问题进行了解读,又带有大量实际的工作技巧、工作思维和工作方法,还包含了很多对于运营的思考、宏观分析和建议,可谓内容完整而全面,同时书中加入了作者亲历的大量真实案例,让全书读起来深入浅出、......一起来看看 《运营之光》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具