解决方案 »

  1.   

    此异常不是验证框架引起,而是SpringMVC不知道你是如何将String类型转换成实体Category使得其无法正确映射对象抛出的转换异常:解决方案:
    想SpringMVC中增加一个Converter,用于映射String到Category,具体详细步骤 度娘 
      

  2.   


    按你这个思路,只要使用Spring 的Validator来验证From 的话,需要验证外键的时候都必须使用Converter去转换类型?不然岂不是都会出现这个类型转换问题?
      

  3.   


    按你这个思路,只要使用Spring 的Validator来验证From 的话,需要验证外键的时候都必须使用Converter去转换类型?不然岂不是都会出现这个类型转换问题?
    这个不是验证的事情,只要你在方法上标明了一个自定义的对象类型需要接受参数,而他偏偏在你的form绑定时是个字符串id都会有SpringMVC的优雅之处也是他不容易开箱即用的劣势,需要做多扩展,我可以给你看一份配置文件,MVC-Servlet的<?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"
    xmlns:ui="http://www.fytech.net/taglib-ui"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.directwebremoting.org/schema/spring-dwr 
    http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd
    http://www.fytech.net/taglib-ui
    http://www.fytech.net/taglib-ui.xsd 
    ">
    <!-- 启动Sping自动代理 -->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
    <property name="proxyTargetClass" value="true"></property><!-- 启动目标类一起代理,而不仅仅是接口信息 -->
    <property name="exposeProxy" value="true"></property><!-- 打开代理上下文 *必选 -->
    </bean>
    <!-- 打开UI组件 -->
    <ui:configuration w3c="HTML_5">
    <ui:bootstrap />
    </ui:configuration>
    <mvc:resources location="/static/" mapping="/static/**"  />
    <mvc:resources location="/uploads/" mapping="/uploads/**"  /> <context:component-scan
    base-package="net.fytech.cms.mvc.**.ctrls"  />
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" p:maxUploadSize="500000000" />
    <!-- 配置Spring采用JSR-303标准的验证代码 -->
    <!-- id必须为messageSource 因为其实Spring的约定,只有id为messageSource的类才会注册为默认的Spring ApplicationContext的默认messageSource -->
    <!-- 次配置用于SpringMVC中手动BindingResult中德rejectValue中的errorCode -->
    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basenames">
    <list>
    <value>classpath:conf/i18n/spring/messages</value>
    </list>
    </property>
    <property name="fileEncodings" value="utf-8"></property>
    <property name="cacheSeconds" value="120"></property>
    </bean>
    <bean id="validatorFactoryBean" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
    <property name="validationMessageSource" ref="messageSource"></property>
    </bean>
    <!-- 配置MVC控制器URL映射注解扫描 -->
    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="alwaysUseFullPath" value="true" />
    <property name="useDefaultSuffixPattern" value="false"></property>
    </bean>
    <bean class="org.springframework.validation.beanvalidation.SpringValidatorAdapter">
    <constructor-arg>
    <ref bean="validatorFactoryBean"/>
    </constructor-arg>
    </bean>
    <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
    <property name="supportedMediaTypes">
    <list>
    <value>text/json;charset=UTF-8</value>
    </list>
    </property>
    </bean>
    <!-- 配置文件上传:限制文件大小不能超过50MB -->
    <bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="52428800"></property>
    </bean>
    <!-- 重新定义SpringMVC的ConversionService -->
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="messageConverters">
    <list>
    <ref bean="mappingJacksonHttpMessageConverter" />
    </list>
    </property>
    <property name="webBindingInitializer">
    <bean class="net.fytech.common.spring32.ExtendsConfigurableWebBindingInitializer">
    <property name="conversionService">
    <bean class="net.fytech.portal.common.mvc.BeanIdFormattingConversionService" />
    </property>
    <property name="validator" ref="validatorFactoryBean"></property>
    <property name="bindingInitializers">
    <array>
      <bean class="net.fytech.portal.common.mvc.DateConverter"></bean>
    </array>
    </property>
    </bean>
    </property>
    </bean>
    <bean id="handlerExceptionResolver" class="net.fytech.portal.common.hander.CommonHandlerExceptionResolver">
    <property name="debug" value="true"></property>
    </bean>
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix">
    <value>/WEB-INF/views</value>
    </property>
    <property name="suffix">
    <value>.jsp</value>
    </property>
    </bean>
    <!-- 加载Hibernate Session生命周期拦截 -->
    <bean id="controllerSessionInterceptor" class="net.fytech.portal.common.db.ControllerSessionInterceptor">
    <property name="sessionFactory" ref="sessionFactory" />
    <property name="openSessionInView" value="false"></property><!-- 测试用,正式使用时将其设置为false,不依赖OpenSessionInView -->
    </bean>
    <bean class="net.fytech.portal.common.db.ControllerMatchPointcutAdvisor">
    <property name="advice" ref="controllerSessionInterceptor" />
    </bean>
    <bean class="net.fytech.cms.security.SecurityListener">
    <property name="work" value="true"></property>
    </bean>
    <!-- 启动权限配置
     -->
    <bean id="securityMethodInterceptor" class="net.fytech.security.advisor.SecurityMethodInterceptor">
    <property name="errorPath" value="/common/security"></property>
    </bean>
    <bean class="net.fytech.security.advisor.SecurityPointcutAdvisor">
    <property name="advice" ref="securityMethodInterceptor"></property>
    </bean>
    </beans>
      

  4.   


    按你这个思路,只要使用Spring 的Validator来验证From 的话,需要验证外键的时候都必须使用Converter去转换类型?不然岂不是都会出现这个类型转换问题?
    这个不是验证的事情,只要你在方法上标明了一个自定义的对象类型需要接受参数,而他偏偏在你的form绑定时是个字符串id都会有
    [/code]
    怎么在自己的方法上标明自定义的对象类型来接受需要的参数?
      

  5.   

    知道是这个问题,是想问下这个问题该怎么解决,不清楚spring这个类型转换他是怎么转换的
      

  6.   

    article中的category是个字符串。但校验框架认为是Category类型的对象,所以尝试将article中的类别字符串强行转换为Category,所以出现错误。请把article,Categoryl两个实体类贴出了看看。 
      

  7.   

    知道是这个问题,是想问下这个问题该怎么解决,不清楚spring这个类型转换他是怎么转换的你这是加载页面出现的错误?
      

  8.   

    --article--
    /**
     *        (c) 2010 Shanghai SDGroup Information GmbH
     *
     *        http://www.sdgroup.com/
     */
    package com.joven.model;import java.util.Date;import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.ManyToOne;
    import javax.persistence.Table;import org.hibernate.annotations.AccessType;/**
     * 
     *文章
     * @author      $JKe$
     * @version      $Revision$ 2013-11-7上午11:24:05
     **/
    @Entity
    @AccessType("field")
    @Table(name="tbl_article")
    public class Article extends BaseEntity<Article>{

    /**
     * 
     */
    private static final long serialVersionUID = 981157642697368414L; /**
     * 文章名称
     */
    private String name;

    /**
     * 文章内容
     */
    private String content;

    /**
     * 创建时间
     */
    private Date createDate;

    /**
     * 创建人
     */
    @ManyToOne(fetch = FetchType.EAGER)
    private User createUser;

    /**
     * 修改时间
     */
    private Date updateDate;

    /**
     * 修改人
     */
    @ManyToOne(fetch = FetchType.EAGER)
    private User updateUser;

    /**
     * 栏目
     */
    @ManyToOne(fetch = FetchType.EAGER)
    private Category category;

    /**
     * 作者
     */
    private String author;


    /**
     * 置顶
     */
    private boolean isTop;

    /**
     * 置顶顺序
     */
    private Integer topNumber; 

    private boolean isDelete; 
    /*--------------------------------------------
     |             C O N S T A N T S             |
     ============================================*/ public String getName() {
    return name;
    } public void setName(String name) {
    this.name = name;
    } public String getContent() {
    return content;
    } public void setContent(String content) {
    this.content = content;
    } public Date getPublishDate() {
    return createDate;
    } public void setPublishDate(Date publishDate) {
    this.createDate = publishDate;
    } public Category getCategory() {
    return category;
    } public void setCategory(Category category) {
    this.category = category;
    } public String getAuthor() {
    return author;
    } public void setAuthor(String author) {
    this.author = author;
    } public Integer getTopNumber() {
    return topNumber;
    } public void setTopNumber(Integer topNumber) {
    this.topNumber = topNumber;
    } public Date getCreateDate() {
    return createDate;
    } public void setCreateDate(Date createDate) {
    this.createDate = createDate;
    } public User getCreateUser() {
    return createUser;
    } public void setCreateUser(User createUser) {
    this.createUser = createUser;
    } public Date getUpdateDate() {
    return updateDate;
    } public void setUpdateDate(Date updateDate) {
    this.updateDate = updateDate;
    } public User getUpdateUser() {
    return updateUser;
    } public void setUpdateUser(User updateUser) {
    this.updateUser = updateUser;
    } public boolean isTop() {
    return isTop;
    } public void setTop(boolean isTop) {
    this.isTop = isTop;
    } public boolean isDelete() {
    return isDelete;
    } public void setDelete(boolean isDelete) {
    this.isDelete = isDelete;
    }
    }
    --Category--
    package com.joven.model;import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.ManyToOne;
    import javax.persistence.Table;import org.hibernate.annotations.AccessType;/**
     * 栏目实体
     * 保存各个栏目信息 
     * 可以父子递归进行二层,三层菜单
     */
    @Entity
    @AccessType("field")
    @Table(name = "tbl_category")
    public class Category extends BaseEntity<Category> implements IAuditLog {    private static final long serialVersionUID = 7911776760953438623L;    /**
         * 模块名称 
         */
        @Column(unique = true)
        private String name;    /**
         * 模块英文名称 
         */
        @Column(unique = true)
        private String categoryName;    
        /**
         * 模块顺序:比如在菜单中各个菜单的先后出现顺序 
         */
        private Integer orderNumber;    /**
         * 父模块
         */
        @ManyToOne
        private Category parentCategory; public String getName() {
    return name;
    } public void setName(String name) {
    this.name = name;
    } public String getCategoryName() {
    return categoryName;
    } public void setCategoryName(String categoryName) {
    this.categoryName = categoryName;
    } public Integer getOrderNumber() {
    return orderNumber;
    } public void setOrderNumber(Integer orderNumber) {
    this.orderNumber = orderNumber;
    } public Category getParentCategory() {
    return parentCategory;
    } public void setParentCategory(Category parentCategory) {
    this.parentCategory = parentCategory;
    } @Override
    public String getEntityClassName() {
    return Category.class.getName();
    }
        
    }
    ----
    category是个实体,不是加载出错,是验证后error里面抛到页面的error信息。在Controtller接受from里传过来的值得时候Article中Cageory是空的,接收不到值。
      

  9.   

    ValidationUtils.rejectIfEmptyOrWhitespace(errors, "category","category.required","category is required");这个只能校验字符串,数字等。category属性不是字符串。像这样的对象校验需要在校验器中自己写校验逻辑。
    解决办法:注释上面这句代码就不报错了!