无法将类型'java.lang.String'的属性值转换为所需类型

时间:2015-01-19 15:37:38

标签: java spring jsp spring-mvc data-binding

我使用的是Spring 3.2.4,我在验证,数据绑定和类型转换方面遇到了问题: 拥有此域类

import static javax.persistence.GenerationType.SEQUENCE;

import java.util.Comparator;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Transient;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.jboss.envers.Versioned;


@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@ParsedByDiff(fieldName="language")
@Entity
@SequenceGenerator(name = "languageSeq", sequenceName = "SEQ_LANGUAGE", allocationSize=1)
@Versioned
public class Language {

    public static final String D_NAME = "name";
    public static final String D_NATIVE_NAME = "nativeName";
    public static final String D_ORDER = "order";

    private Long id;

    /**
     * Name of the language.
     */
    private String name;

    /**
     * Name of the language in the language.
     */
    private String nativeName;

    /**
     * Member state character code.
     */
    private String code;

    private int order;

    public Language(){

    }

    @Id
    @GeneratedValue(strategy = SEQUENCE, generator = "languageSeq")
    public Long getId(){
        return id;
    }


    public void setId(Long newVal){
        id = newVal;
    }

    @ParsedByDiff(fieldName="language")
    public String getName(){
        return name;
    }


    public void setName(String newVal){
        name = newVal;
    }

    /**
     * @return the nativeName
     */
    @Column(name="NATIVE_NAME")
    public String getNativeName() {
        return nativeName;
    }



    /**
     * @return the order
     */
    @Column(name="LANG_ORDER")
    public int getOrder() {
        return order;
    }

    /**
     * @param order the order to set
     */
    public void setOrder(int order) {
        this.order = order;
    }

    /**
     * @param nativeName the nativeName to set
     */
    public void setNativeName(String nativeName) {
        this.nativeName = nativeName;
    }

    /**
     * @return the code
     */
    public String getCode() {
        return code;
    }

    /**
     * @param code the code to set
     */
    public void setCode(String code) {
        this.code = code;
    }

    /**
     * Required to work with Spring's <code>&lt;form:select&gt;</code> tag.
     */
    @Transient
    public String getOptionValue() {
        return id == null ? "" : id.toString();
    }

    /**
     * Compares using id field only. Language instances are immutable objects
     * so this strategy should work well.
     */
    @Override
    public boolean equals(Object object) {
        boolean result = false;

        if (this == object) {
            result = true;
        }
        else if (object instanceof Language) {
            Language language = (Language)object;
            result = id.equals(language.id);
        }

        return result;
    }

    /**
     * Aligned to equals method returns id field hash code.
     */
    @Override
    public int hashCode() {
        return id.hashCode();
    }

    public static class LanguageWrapper {

        private Language language;

        public LanguageWrapper(Language language) {
            this.language = language;
        }

        public Language getLanguage() {
            return language;
        }

        @Override
        public boolean equals(Object obj) {
            return this.language.getId().equals(((LanguageWrapper)obj).getLanguage().getId());
        }

        @Override
        public int hashCode() {
            return this.getLanguage().getId().hashCode();
        }
    }


    public static class LanguageWrapperNameComparator implements Comparator<LanguageWrapper> {
        public int compare(LanguageWrapper o1, LanguageWrapper o2) {
            return o1.getLanguage().getName().compareToIgnoreCase(o2.getLanguage().getName());
        }
    }
}

我在控制器的bind方法中注册它:

/**
 *
 */
@SuppressWarnings("deprecation")
@Override
protected void initBinder(
        HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {

    super.initBinder(request, binder);

    binder.registerCustomEditor(Language.class, "language", new DomainObjectPropertyEditor<Language>(new DomainObjectConverter<Language>() {
        @Override public Long getId(Language object) { return object.getId(); }
        @Override public Language getObject(Long id) { return languageService.findById(id); }
    }));
}

和DomainObjectPropertyEditor类

public class DomainObjectPropertyEditor<T> extends PropertyEditorSupport {

    private DomainObjectConverter<T> domainObjectConverter;

    /**
     * Forces clients to provide proper converter.
     * @param domainObjectConverter
     */
    public DomainObjectPropertyEditor(DomainObjectConverter<T> domainObjectConverter) {
        this.domainObjectConverter = domainObjectConverter;
    }

    @Override
    public String getAsText() {
        @SuppressWarnings("unchecked")
        T object = (T)getValue();
        if (object == null) {
            return super.getAsText();
        }
        return String.valueOf(domainObjectConverter.getId(object));
    }

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        T object = null;
        if (text != null && !text.isEmpty())
            object = domainObjectConverter.getObject(Long.valueOf(text));
        setValue(object);
    }
}

并在JSP中:

<form:select path="language" >                  
            <c:forEach items="${languageList}" var="language">
                <form:option value="${language}">${language.nativeName} (${language.code})</form:option>
            </c:forEach>
        </form:select>

提交页面时出现此错误:

调试时,这是方法

的BindException错误的值
    protected final ModelAndView showForm(
            HttpServletRequest request, BindException errors, String viewName, Map controlModel)
            throws Exception {
  ...
}

org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'command' on field 'language': rejected value [com.domain.Language@1]; codes [typeMismatch.command.language,typeMismatch.language,typeMismatch.com.domain.Language,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [command.language,language]; arguments []; default message [language]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'com.domain.Language' for property 'language'; nested exception is java.lang.IllegalStateException: 
Cannot convert value of type [java.lang.String] to required type [com.domain.Language] for property 'language': no matching editors or conversion strategy found]

0 个答案:

没有答案