¿Por qué recibo IllegalArgumentException Can no convierte el valor de tipo String al tipo requerido del producto, en la primavera?

StackOverflow https://stackoverflow.com/questions/4368828

Pregunta

Recibo la excepción

Error al valor de la propiedad de convertir Tipo [java.lang.String] para requerido tipo [beans.Product] para propiedad producto; excepción anidada es java.lang.IllegalArgumentException: No se puede convertir el valor de tipo de [Java.lang.String] para tipo requerido [Beans.Product] propiedad para el producto: no editores coincidentes o conversión estrategia encontró

en los errores de errores de objeto, incluso antes de que mi DetailProductValidator comienza la validación a través del método de validación.

No entiendo por qué la primavera hace eso. No tengo ningún campo de entrada que se asigna directamente a la propiedad del producto / objeto. Sólo tiene que utilizar las propiedades del objeto de producto en el JSP. Por ejemplo, yo utilizo:

<form:options items="${dpBackObj.product.colorMap}"/>
<!-- or -->
${dpBackObj.product.priceInDollars}

pero nunca uso:

<form:input path="product"/>

¿Puede alguien por favor explique por qué sucede esto? Y tal vez informarme de una solución sencilla?

La configuración de frijol para el controlador es:

    <!-- DETAIL PRODUCT FORM CONTROLLER -->
<bean id="productDetailFormController" name="/detail.htm /addToCart.htm" 
        class="detailProduct.DetailProductFormController">
    <property name="sessionForm" value="true" />
    <property name="commandName" value="dpBackObj" />
    <property name="commandClass" value="detailProduct.DetailProductBackingObject" />
    <property name="validator">
        <bean class="detailProduct.DetailProductValidator" />
    </property>
    <property name="formView" value="detail" />
    <property name="successView" value="redirect:/viewCart.htm" />
    <property name="cartService" ref="cartServiceImpl"/>
</bean>

El objeto respaldo para el DetailProductFormController es:

public class DetailProductBackingObject {
    private String quantityOverflowError;
    private Product product;
    private int quantity;
    private ShoppingCart shoppingCart;
    private long sizeId;
    private long colorId;
    public DetailProductBackingObject() {
        this.product = new Product();
        this.sizeId = -1;
        this.colorId = -1;
    }
    //getters and setters
}

Si necesita alguna otra información, proporcionaré. Estoy usando la primavera 2.5.5.

Saludos Saludos, Déspota

EDIT1 ( debido a la petición de axtavt ):

<form:form method="post" commandName="dpBackObj">
<table width="730" border="0" cellspacing="0" cellpadding="0">
    <c:if test="${!empty dpBackObj.quantityOverflowError}">
        <tr>
            <td>
                <c:out value="${dpBackObj.quantityOverflowError}"/>
            </td>
        </tr>
    </c:if>
    <spring:bind path="dpBackObj.*">
        <c:if test="${not empty status.errorMessages}">
            <div class="val-summary text-error" id="errorDivId">
                <div style="" class="val-summary text-error" id="errorDivId">
                    <fmt:message key="detail.error.header"/>
                    <ul>
                        <c:forEach items="${status.errorMessages}" var="error">
                            <li><c:out value="${error}"/></li>
                        </c:forEach>
                    </ul>
                </div>
            </div>
        </c:if>
    </spring:bind>
    <tr>
        <td width="310" align="left" valign="top">
            <img src="${imagesPath}/${dpBackObj.product.largeImageUrl}" alt="${dpBackObj.product.description}" />
        </td>
        <td width="420" align="left" valign="top">
            <div id="tls_detPName">
                <c:out value="${dpBackObj.product.name}"></c:out>
            </div>
            <div >  
                <strong class="numeric">${dpBackObj.product.priceInDollars}</strong>
            </div>
            <div id="tls_detPDescLong">
                ${dpBackObj.product.largeDescription}
                <br />
            </div>
            <div >
                <table cellpadding="2" border="0">
                    <tr>
                        <td align="right">
                            <label for="p_sizes" class="label"><fmt:message key="viewCart.Size"/></label>
                        </td>
                        <td>
                            <form:select path="sizeId" > 
                                <form:option  value="-1" label="x"/> 
                                <form:options items="${dpBackObj.product.sizeMap}"/>
                            </form:select>
                        </td>
                    </tr>
                    <tr>
                        <td align="right">
                            <label for="p_colors" class="label"><fmt:message key="viewCart.Color"/></label>
                        </td>
                        <td>
                            <form:select path="colorId" > 
                                <form:option value="-1" label="y"/> 
                                <form:options items="${dpBackObj.product.colorMap}"/>
                            </form:select>
                        </td>
                    </tr>
                </table>
            </div>
            <div id="tls_addToCart">
                <div >
                    <label for="quantityId" class="label"><fmt:message key="viewCart.Quantity"/>:</label>
                    <form:input path="quantity" onkeypress="return checkForNumber(this, event)" maxlength="10" size="3" id="quantityId" cssClass="textbox-center"/>
                    <input type="image" name="addToCartButtonName" src="${imagesPath}/addToCartBtn.jpg" /> 
                </div>
            </div>
        </td>
    </tr>
</table>
</form:form>

Edit2 ( debido a la petición de JacobM ): Este es mi Validador:

public class DetailProductValidator implements Validator {
    public boolean supports(Class clazz) {
        return DetailProductBackingObject.class.equals(clazz);
    }

    public void validate(Object obj, Errors errors) {
        DetailProductBackingObject detailProductBackingObject = (DetailProductBackingObject) obj;
        if (detailProductBackingObject.getSizeId() == -1) {
            errors.rejectValue("sizeId", "error.detail.jsp.choose.size", null, "Input size.");
        }
    }
}

Cuando llego a la línea DetailProductBackingObject detailProductBackingObject = que ya tienen el error.
La conversión de los parámetros de la petición a las propiedades del objeto de respaldo sucede en http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/web/servlet/mvc/BaseCommandController.html . Esto es lo que dice la primavera sobre la conversión:

Poblando usando parámetros de la petición y PropertyEditors: Al recibir una solicitud, cualquier BaseCommandController intentará llenar el comando objeto utilizando los parámetros de la petición. Esto se hace usando la típica y conocida propiedad JavaBeans notación. Cuando un parámetro de la petición Existe llamado 'primerNombre', la marco intentará llamar setFirstName ([valor]) hacer pasar la valor del parámetro. Anidado propiedades son, por supuesto compatibles. Por ejemplo, un parámetro llamado 'Address.city' dará lugar a una getAddress (). setCity ([valor]) llamada en la clase de comandos.

Es importante darse cuenta de que son no se limita a los argumentos de cadena de sus JavaBeans. Utilizando la PropertyEditor-noción suministrada por el paquete java.beans, que será capaz de transformar cadenas a objetos Y a la inversa. Por ejemplo setLocale (Locale loc) es perfectamente posible que un parámetro de petición de llamada locale tiene un valor de en, siempre como se registre la adecuada PropertyEditor en el controlador (véase initBinder () para obtener más información sobre esa materia.

validadores: Después de que el controlador tiene poblada con éxito el comando objeto con parámetros de la solicitud, se utilizará cualquier configurado validadores para validar el objeto. resultados de la validación serán puestos en una Errores de objeto que se puede utilizar en una Ver para rendir cualquier problema de entrada.

¿Fue útil?

Solución

Ya que no puedo ver nada malo con la forma, la única posible razón por la que puedo imaginar es que usted tiene una product llamado parámetro en la URL de la página de formulario.

Si es así, puede cambiar sus URL o el uso DataBinder.setDisallowedFields() desactivar el intento de obligar a ese parámetro.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top