springboot~对@RequestParam中Date参数的适配

@RequestParam中的Date类型的参数,如果前端给一个2001-01-01在后端默认是不认的,我们在后端需要对这种情况进行适配,我们可以通过@ControllerAdvice注解来拦截请求,然后对Date参数进行转换,最终实现我们的需求。

  • 实现org.springframework.core.convert.converter.Convert接口,来完成日期格式的转换
    public class CourseDateConverter implements Converter<String, Date> {
        private static final String dateFormat = "yyyy-MM-dd HH:mm:ss";
        private static final String dateFormata = "yyyy-MM-dd HH:mm:ss";
        private static final String shortDateFormat = "yyyy-MM-dd";
        private static final String shortDateFormata = "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(":")) {
                        // yyyy-MM-dd HH:mm:ss 格式
                        formatter = new SimpleDateFormat(dateFormat);
                    } else {
                        // yyyy-MM-dd 格式
                        formatter = new SimpleDateFormat(shortDateFormat);
                    }
                    return formatter.parse(value);
                } else if (value.matches(timeStampFormat)) {
                    //时间戳
                    Long lDate = new Long(value);
                    return new Date(lDate);
                } else if (value.contains("/")) {
                    SimpleDateFormat formatter;
                    if (value.contains(":")) {
                        // yyyy/MM/dd HH:mm:ss 格式
                        formatter = new SimpleDateFormat(dateFormata);
                    } else {
                        // yyyy/MM/dd 格式
                        formatter = new SimpleDateFormat(shortDateFormata);
                    }
                    return formatter.parse(value);
                }
            } 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));
        }
    }

  • 通过@InitBinder来注入转换器
    @InitBinder作用于@Controller中的方法,表示为当前控制器注册一个属性编辑器,对WebDataBinder进行初始化,且只对当前的Controller有效。
  • @InitBinder执行时机
    @InitBinder注解被解析的时机,是其所标注的方法,在该方法被请求执行之前。同时@InitBinder标注的方法是可以多次执行的,也就是说来一次请求就执行一次@InitBinder解析。
  • @InitBinder执行原理
    当某个Controller上的第一次请求,由SpringMVC前端控制器匹配到该Controller之后,根据Controller的 class 类型来查找所有标注了@InitBinder注解的方法,并且存入RequestMappingHandlerAdapter里的 initBinderCache 缓存中。等下一次请求执行对应业务方法之前,会先走initBinderCache缓存,而不用再去解析@InitBinder。
@ControllerAdvice
public class TimeControllerHandler {
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        GenericConversionService genericConversionService = (GenericConversionService) binder.getConversionService();
        if (genericConversionService != null) {
            genericConversionService.addConverter(new CourseDateConverter());
        }
    }
}

这样,前端传入的日期参数?fromDate=2001-01-01&endDate=2015-01-01,也是可以被后端成功处理的。

上一篇:Java 使用MySQL,根据数据库生日字段(字段格式为:yyyy-MM-dd)计算用户年龄


下一篇:Javascript常用工具类封装