一、需求分析
默认情况下,如果注入Date类型的对象,会报如下错误:
Failed to convert value of type 'java.lang.String' to required type 'java.util.Date'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.util.Date] for value 'xxxx-xx-xx'; nested exception is java.lang.IllegalArgumentException
原代码如下:
@RequestMapping(value="/generateReport.json",method = RequestMethod.GET) @ResponseBody public JSONObject generateReport(Date date){ JSONObject ret = new JSONObject(); /***********/ return ret; }
二、解决方法
虽然这里可以直接改为String类型,然后手动去解析,但是如果项目中这种需求出现多次的话,那每次都去手动解析并不是一种较好的选择。
所以这里,我通过自定义参数解析器加注解来实现,用注解可以更加灵活!
2.1、先写一个注解类
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.PARAMETER}) public @interface RequestFormat { String value() default "yyyy-MM-dd HH:mm:ss"; }
2.2、调用该注解类
@RequestMapping(value="/generateReport.json",method = RequestMethod.GET) @ResponseBody public JSONObject generateReport(@RequestFormat("yyyy-MM-dd") Date date){ JSONObject ret = new JSONObject(); /***代码写的不好,就不贴了***/ return ret; }
2.3、编写自定义参数解析器
我这里写的比较基础,后续如果有更多的功能要求,再完善。本文也只是记录自己解决该问题的一种思路!
package com.renyiwei.web.resolver; import com.github.miemiedev.mybatis.paginator.domain.PageBounds; import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.MethodParameter; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; import java.beans.PropertyEditorSupport; import java.lang.annotation.Annotation; import java.text.SimpleDateFormat; import java.util.Date; public class CustomDateArgumentResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter methodParameter) { // 获取参数类型 Class<?> paramType = methodParameter.getParameterType(); return Date.class.isAssignableFrom(paramType) && methodParameter.getParameterAnnotation(RequestFormat.class)!=null; } @Override public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception { RequestFormat requestFormat = methodParameter.getParameterAnnotation(RequestFormat.class); String format = requestFormat.value(); SimpleDateFormat sdf = new SimpleDateFormat(format); DefaultParameterNameDiscoverer discover = new DefaultParameterNameDiscoverer(); //获取方法的函数形参名称 String[] parameterNames = discover.getParameterNames(methodParameter.getMethod()); //获取当前参数的名称 String parameterName = parameterNames[methodParameter.getParameterIndex()]; //获取值 String requestValue = nativeWebRequest.getParameter(parameterName); return sdf.parse(requestValue); } }
2.4、配置该参数解析器
在Springboot中配置该参数解析器
package com.renyiwei.sprintboot; @Configuration //@EnableWebMvc @ControllerAdvice public class SpringMvcConfig implements WebMvcConfigurer { @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { argumentResolvers.add(new CustomDateArgumentResolver()); } }