在用Springmvc的日期类型作为参数的时候,会碰到
org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type ' java.lang.String' to required type 'java.util.Date'; nested exception is java.lang. IllegalStateException: Cannot convert value of type [java.lang.String] to required type [java.util.Date]: no matchingeditors or conversion strategy found 对应不能绑定问题一般有下面几个方法: 一、Spring3的源码,略微做了下修改:在Spring3的core包下找到
org.springframework.core.convert.support.GenericConversionService.convert(Object, TypeDescriptor, TypeDescriptor);这个方法然后在assertNotNull(sourceType, targetType);
这个方法然后在assertNotNull(sourceType, targetType); 这句话的下面添加:
if(targetType.getType().getName().equals("java.util.Date") && source instanceof String){ String date = (String)source; try { source = YMD_DATETIME_FORMAT.parse(date); } catch (ParseException e) { try { source = YMDHM_DATETIME_FORMAT.parse(date); } catch (ParseException e1) { try { source = YMDHMS_DATETIME_FORMAT.parse(date); } catch (ParseException e2) { source = null; } } } sourceType = targetType; }
最后重新编译打包core包 这样当遇到Date类型的时候就把数据转换成Date类型的,接下去就不会报错了 这种方法不推荐,修改了源代码,日期类型格式非灵活性。不建议采用 二、在mvc配置的那个xml中添加如下代码:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="cacheSeconds" value="0" /> <property name="webBindingInitializer"> <bean class="WebBinding" /> </property> </bean>
添加WebBinding
import java.util.Date; import org.springframework.beans.propertyeditors.CustomDateEditor; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.support.WebBindingInitializer; import org.springframework.web.context.request.WebRequest; public class WebBinding implements WebBindingInitializer { @Override public void initBinder(WebDataBinder binder, WebRequest request) { // 使用spring自带的CustomDateEditor // 解决时间转换问题 // yyyy-MM-dd binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true)); } }
这样虽然可以解决日期类型参数报错问题也不建议采用,这样每个日期类型格式必须 yyyy-MM-dd 三、采用自定义注解方式解决日期类型参数绑定问题 1、 定义一个自定义日期类型解析器注解
package org.dongtian.sys.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 日期类型解析器注解 * @author gaoyuandong * @mailto 466862016@qq.com * @date 2015年9月6日 下午2:18:38 */ @Target({ElementType.PARAMETER,ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface DateParser { //名称 String name() default ""; //格式化 String pattern() default "yyyy-MM-dd hh:mm:ss"; }
默认格式为 yyyy-MM-dd hh:mm:ss 2、接下来我们定义一个此日期类型解析器注解对应的解析器(我们实现Springmvc自定义方法参数解析器)
package org.dongtian.sys.web.context; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.dongtian.sys.annotation.DateParser; import org.springframework.beans.BeanUtils; import org.springframework.core.MethodParameter; import org.springframework.web.bind.WebDataBinder; 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; /*** * spring mvc 方法参数或者参数为bean中包含有日期类型的格式解析器 * @author gaoyuandong * @mail 466862016@qq.com * @date 2015年9月13日 下午3:49:39 */ public class DateHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver { private static Logger log = Logger.getLogger(DateHandlerMethodArgumentResolver.class); public boolean supportsParameter(MethodParameter parameter) { //方法参数 DateParser dateParser = parameter.getParameterAnnotation(DateParser.class); if (dateParser != null) { return true; } else { //bean的字段上是否存在@DateParser注解 Class<?> targetType = parameter.getParameterType(); Field[] fields = targetType.getDeclaredFields(); if(fields != null && fields.length >0) { for (int i = 0; i < fields.length; i++) { Field field = fields[i]; if(field.isAnnotationPresent(DateParser.class) == true) { return true; } } } return false; } } /*** * 解析包含有{@link org.dongtian.sys.annotation.DateParser} 注解的参数 */ public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { if(binderFactory == null) return null; if(this.findDateParserAnnotationWithArguement(parameter) == true) { return this.handlerMethodArgumentDateParserAnnotation(parameter,mavContainer,webRequest,binderFactory); } else { return this.handlerBeanArgumentDateParserAnnotation(parameter,mavContainer,webRequest,binderFactory); } } /*** * 解析bean中成员变量 中包含有{@link org.dongtian.sys.annotation.DateParser} 注解的参数 * @author gaoyuandong * @date 2015年9月13日 下午4:39:58 * @param parameter * @param mavContainer * @param webRequest * @param binderFactory * @return */ private Object handlerBeanArgumentDateParserAnnotation(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { Class<?> targetType = parameter.getParameterType(); Object obj = BeanUtils.instantiate(targetType); Field[] fields = targetType.getDeclaredFields(); WebDataBinder binder; try { binder = binderFactory.createBinder(webRequest, null, obj.getClass().getName()); for (Field field : fields) { field.setAccessible(true); String fieldName = field.getName(); Class<?> fieldType = field.getType(); Object arg = null; if(!Modifier.isFinal(field.getModifiers())) { if(!StringUtils.isBlank(webRequest.getParameter(fieldName))) { if(field.isAnnotationPresent(DateParser.class)) { DateParser dateParser = field.getAnnotation(DateParser.class); String pattern = dateParser.pattern(); String key = StringUtils.isBlank(dateParser.name()) ? parameter.getParameterName() : dateParser.name(); //TODO SimpleDateFormat dateFormat = new SimpleDateFormat(pattern); Date date = dateFormat.parse(webRequest.getParameter(fieldName)); arg = date; } else { arg = binder.convertIfNecessary(webRequest.getParameter(fieldName), fieldType, parameter); } } else { arg = getDefaultArgumentValue(fieldType, arg); } field.set(obj, arg); } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } return obj; } /*** * 获取基本数据类型默认的值 * @author gaoyuandong * @date 2015年9月13日 下午5:27:37 * @param fieldType * @param arg * @return */ private Object getDefaultArgumentValue(Class<?> fieldType, Object arg) { if(this.isBasicDataType(fieldType)) { if(fieldType.getName().equals(Boolean.TYPE) ||fieldType.getName().equals(Void.TYPE) ) { } else { arg = 0; } } return arg; } /** * 判定是否为基本数据类型 * @author gaoyuandong * @date 2015年9月13日 下午5:12:53 * @param fieldType * @return */ private boolean isBasicDataType(Class<?> fieldType) { return fieldType.isPrimitive()?true:false; } /*** * {@link org.dongtian.sys.annotation.DateParser} 注解在方法参数中数据绑定 * @author gaoyuandong * @date 2015年9月13日 下午4:19:02 * @param parameter * @param mavContainer * @param webRequest * @param binderFactory * @return * @throws ParseException */ private Object handlerMethodArgumentDateParserAnnotation(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { String[] vals = webRequest.getParameterValues(parameter.getParameterName()); if (vals == null || vals.length == 0) { return null; }else { if (StringUtils.isBlank(vals[0])) { return null; } else { for (Iterator<String> itr = webRequest.getParameterNames(); itr.hasNext();) { String next = itr.next(); log.debug(next + " : " + webRequest.getParameterValues(next)[0]); } DateParser dateParser = parameter.getParameterAnnotation(DateParser.class); String pattern = dateParser.pattern(); String key = StringUtils.isBlank(dateParser.name()) ? parameter.getParameterName() : dateParser.name(); // TODO log.debug(parameter.getParameterName()); SimpleDateFormat dateFormat = new SimpleDateFormat(pattern); Date date = null; try { date = dateFormat.parse(webRequest.getParameterValues(parameter.getParameterName())[0]); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } return date; } } } /*** * 是否存在{@link org.dongtian.sys.annotation.DateParser}注解 * @author gaoyuandong * @date 2015年9月13日 下午4:14:05 * @param parameter * @return true 存在 false 不存在 */ private boolean findDateParserAnnotationWithArguement(MethodParameter parameter) { return parameter.getParameterAnnotation(DateParser.class) == null ? false:true; } }
此类可以解析作用在方法参数上和javabean中的成员变量为date类型上 下面是作用在方法参数上
@RequestMapping("/index") public ModelAndView index(@DateParser(pattern="yyyy-MM-dd")Date createTime,User user, @RequestParam(defaultValue="1")Integer pageNum,@RequestParam(defaultValue="5")Integer pageSize,String userName,String nickName,String email) { ModelAndView andView = new ModelAndView("admin/user/index"); System.err.println(user.getCreateTime()); Page<User> page = new Page<User>(pageNum,pageSize); PageHelper.startPage(page.getPageNum(), page.getPageSize()); List<User> userList = this.userService.findUserList(userName,nickName,email); int userCount = this.userService.findUserCount(userName,nickName,email); page.setTotalCount(userCount); page.setList(userList); andView.addObject("page", page); return andView; }
下面用在java bean上
@RequestMapping("/showDate") @ResponseBody public JsonResult showDate(User user) { return null; }
package org.dongtian.sys.entity; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.dongtian.sys.annotation.DateParser; import org.springframework.format.annotation.DateTimeFormat; import com.fasterxml.jackson.annotation.JsonFormat; /** * 用户信息 * @author gaoyuandong * @mailto 466862016@qq.com * @date 2015年8月25日 下午7:45:40 */ public class User { private Integer userId; private String userName; private String password; private Integer state; private int age; private int sex; private String address; private String mobile; private String email; private Integer userType; private String nickName; @DateParser(pattern="yyyy-MM-dd hh:mm:ss") private Date createTime; private Date updateTime; private Date regTime; private List<Role> roleList = new ArrayList<Role>(); //正常 public final static int USER_STATE_NORMAL = 0; //已删除 public final static int USER_STATE_DELETE = 1; //已经被锁定 public final static int USER_STATE_LOCKED = 2; public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Integer getState() { return state; } public void setState(Integer state) { this.state = state; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getSex() { return sex; } public void setSex(int sex) { this.sex = sex; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getNickName() { return nickName; } public void setNickName(String nickName) { this.nickName = nickName; } @DateTimeFormat(pattern="yyyy-MM-dd hh:mm:ss") @JsonFormat(pattern="yyyy-MM-dd hh:mm:ss") public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } @DateTimeFormat(pattern="yyyy-MM-dd hh:mm:ss") @JsonFormat(pattern="yyyy-MM-dd hh:mm:ss") public Date getUpdateTime() { return updateTime; } public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } @DateTimeFormat(pattern="yyyy-MM-dd hh:mm:ss") @JsonFormat(pattern="yyyy-MM-dd hh:mm:ss") public Date getRegTime() { return regTime; } public void setRegTime(Date regTime) { this.regTime = regTime; } public Integer getUserType() { return userType; } public void setUserType(Integer userType) { this.userType = userType; } public List<Role> getRoleList() { return roleList; } public void setRoleList(List<Role> roleList) { this.roleList = roleList; } }
4、最后我们将我们的自定义方法参数解析器在RequestMappingHandlerAdapter配置
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="messageConverters"> <list> <ref bean="mappingJacksonHttpMessageConverter"/> </list> </property> <property name="customArgumentResolvers"> <list> <ref bean="dateHandlerMethodArgumentResolver"/> </list> </property> </bean> <bean id="dateHandlerMethodArgumentResolver" class="org.dongtian.sys.web.context.DateHandlerMethodArgumentResolver"></bean>
这样会更加灵活不得不承认springmcv做的如此强大,给我们更好的扩展接口这样我们不光可以解决日期类型错误,我们还可以把当前登录用户信息当做方法参数等等。
相关推荐
这是一个可以运行的ecplise中的mvc题目:从index.jsp跳转到success.jsp。
解决SpringMVC关于前台日期作为实体类对象参数类型转换错误的问题有多种方法,下面我们将介绍三种解决方案。 解决方案1:使用@DateTimeFormat注解 在对应的实体类属性上加入@DateTimeFormat(pattern = "yyyy-MM-dd...
本文将详细介绍如何在SpringMVC中后台转换JSON格式,以解决406错误问题。 406错误通常发生在客户端发送了Accept头,表明它期望接收某种特定类型的数据,但服务器无法提供这种类型的数据。在Ajax请求中,这个Accept...
从Spring 3开始,SpringMVC引入了更为强大的数据绑定框架,解决了上述问题,并提供了更加灵活和强大的数据转换、验证及格式化能力。 ##### 1. 类型转换 - **核心组件**:`ConversionService`接口及其具体实现类`...
针对上述问题,有两种主要的方法可以解决 Spring MVC 无法直接接收 List 类型参数的问题: ##### 方法一:使用 jQuery 的 traditional 参数 在 AJAX 请求中添加 `traditional: true` 参数,以确保数组类型的参数被...
SPRINGMVC 406问题解决方案 SPRINGMVC 是一个基于 Java 的 Web 应用程序框架,它提供了一个灵活的方式来开发 Web 应用程序。然而,在使用 SPRINGMVC 时,可能会遇到一些问题,例如 406 错误。本文将详细介绍 ...
SpringMVC自定义参数转换实现代码解析 在 SpringMVC 框架中,参数绑定是指将 HTTP 请求中的参数绑定到控制器的方法参数上。SpringMVC 提供了多种参数绑定的方式,包括默认的参数绑定、简单类型参数绑定、POJO 类型...
### 多线程解决方案 在Java中,多线程是实现并发执行任务的关键。SpringMVC提供了一种在服务层实现多线程的方法,以提高程序的执行效率和响应速度。以下是一些关键概念: 1. **ThreadPoolTaskExecutor**:Spring...
SpringMVC Tomcat控制台乱码问题解决方案 本文主要介绍了SpringMVC Tomcat控制台乱码问题解决方案,该解决方案通过示例代码进行了详细的介绍,对大家的学习或者工作具有一定的参考学习价值。下面将对该解决方案进行...
在IT行业中,编程语言的错误...总的来说,这个压缩包提供了丰富的资源,帮助开发者在遇到各类技术问题时找到解决方案,提升他们的编程技能和问题解决能力。通过深入学习和实践,可以有效提高开发效率,降低项目风险。
SpringMVC参数绑定是指将用户请求的参数绑定到控制器的方法参数中。例如,使用@PathVariable注解绑定URL中的参数,使用@RequestParam注解绑定请求参数。 五、SSM整合 SSM整合是指将SpringMVC、MyBatis和Spring框架...
问题2:前端参数未转换为JSON格式,会导致403错误。需使用`JSON.stringify()`将JavaScript对象转化为JSON字符串。 3. 传数组参数 在POST请求中,可以使用@RequestParam接收数组。当数组作为请求参数时,需要在参数...
SpringMVC 日期类型接收空值异常问题解决方法 SpringMVC 框架中,日期类型接收空值异常问题是一个常见的问题。这个问题的出现是因为 SpringMVC 框架在接收到空字符串时,无法自动将其转换为 Date 类型。解决这个...
在 SpringMVC 中,有两种方式可以实现日期参数的传递,一种是使用注解的方式,另一种是使用类型转换的方式。 使用注解的方式 在使用注解的方式中,我们需要在 Controller 层中使用 `@InitBinder` 注解来实现日期...
参数绑定过程主要介绍了SpringMVC参数绑定的机理和使用@RequestParam注解指定request请求的参数名绑定到哪个方法形参上。自定义参数绑定部分主要介绍了使用WebDataBinder和使用WebBindingInitializer两种方式实现...
"SpringMVC请求/响应乱码问题解决方案解析" SpringMVC请求/响应乱码问题是指在使用SpringMVC框架进行Web开发时,请求参数或响应内容出现乱码的问题。这种问题的出现是由于字符编码的不一致所引起的。本文将详细介绍...
SpringMVC解决中文乱码问题 SpringMVC 框架中,中文乱码问题是常见的问题之一。解决这个问题的关键是正确地配置字符编码。下面我们将详细介绍 SpringMVC 中解决中文乱码问题的思路和方法。 配置文件中的字符编码 ...
三、解决日期类型转换问题 1. **使用`@InitBinder`方法** `@InitBinder`注解用于初始化数据绑定过程,我们可以在这个方法中添加自定义的日期格式化器。例如,我们可以创建一个全局的日期格式: ```java @...
解决这个问题的关键在于正确配置SpringMVC中的消息转换器,确保它能够正确处理文件上传请求并返回正确的响应类型。以下是一种可行的解决方案: 1. **配置消息转换器**: 在SpringMVC配置文件中,需要配置一个消息...