Pourquoi dois-je obtenir IllegalArgumentException ne peut pas convertir la valeur de type String au produit de type requis, au printemps?
-
09-10-2019 - |
Question
Je reçois l'exception
Impossible de convertir la valeur de la propriété de type [java.lang.String] pour requis Type [beans.Product] pour les biens produit; exception imbriquée est java.lang.IllegalArgumentException: Impossible de convertir la valeur de type [Java.lang.String] type requis [Beans.Product] pour les produits de la propriété: pas les éditeurs correspondants ou conversion stratégie trouvée
les erreurs erreurs objectent même avant mon DetailProductValidator commence la validation par la méthode de validation.
Je ne comprends pas pourquoi Spring fait ça. Je n'ai pas un champ d'entrée qui est mappé directement à la propriété / objet produit. Je viens d'utiliser les propriétés de l'objet produit dans le jsp. Par exemple, j'utilise:
<form:options items="${dpBackObj.product.colorMap}"/>
<!-- or -->
${dpBackObj.product.priceInDollars}
mais je ne l'utilise jamais:
<form:input path="product"/>
Quelqu'un peut-il expliquer pourquoi s'il vous plaît cela se produit? Et peut-être me faire part d'une solution simple?
La configuration des beans pour le contrôleur est:
<!-- 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>
L'objet de support pour le DetailProductFormController est:
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 vous avez besoin d'autres informations, je fournirai. J'utilise Spring 2.5.5.
Cordialement,
Despot
EDIT1 ( en raison de la demande 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 ( en raison de la demande de JacobM ): Ceci est mon validateur:
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.");
}
}
}
Quand je tends la ligne DetailProductBackingObject detailProductBackingObject = J'ai déjà l'erreur.
La conversion de des paramètres de demande pour les propriétés de l'objet de support qui se passe dans http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/web/servlet/mvc/BaseCommandController.html . C'est ce printemps dit à propos de la conversion:
Peuplement en utilisant des paramètres de demande et PropertyEditors: lors de la réception d'un demande, tout BaseCommandController tentera de remplir la commande objet en utilisant les paramètres de la requête. Cela se fait en utilisant le typique et JavaBeans bien connue propriété notation. Lorsqu'un paramètre de requête nommé « prenom » existe, le cadre tentera d'appeler setFirstName ([value]) faire passer le La valeur du paramètre. emboîtée propriétés sont bien sûr pris en charge. Par exemple, un paramètre nommé « Address.city » entraînera une getAddress (). setCity ([value]) sur appel la classe de commande.
Il est important de réaliser que vous êtes sans s'y limiter aux arguments de chaîne dans vos JavaBeans. En utilisant le PropertyEditor-notion telle que fournie par le paquet java.beans, vous serez capable de transformer des chaînes en objets et l'inverse. Par exemple setLocale (loc Locale) est parfaitement possible pour un paramètre de requête nommé locale ayant une valeur en tant que vous enregistrez le approprié PropertyEditor dans le contrôleur (voir initBinder () pour plus d'informations sur cette question.
validateurs: Après que le contrôleur a peuplé avec succès la commande objet avec les paramètres de la demande, il utilisera tout configuré valideurs pour valider l'objet. Les résultats de validation seront mis en Erreurs objet qui peut être utilisé dans un En vue de rendre les problèmes d'entrée.
La solution
Depuis que je ne vois rien de mal avec la forme, la seule raison possible, je peux imaginer est que vous avez un paramètre nommé product
dans l'URL de votre page de formulaire.
Si oui, vous pouvez modifier vos URL ou utiliser DataBinder.setDisallowedFields()
pour désactiver la tentative de lier ce paramètre.