2010-12-06 7 views
4

Ich erhalte die AusnahmeWarum bekomme ich IllegalArgumentException Kann den Wert des Typs String nicht in den erforderlichen Typ Produkt konvertieren, im Frühjahr?

fehlgeschlagen Eigenschaftswert von Typ [java.lang.String] auf die gewünschte Typ [beans.Product] für Eigenschaft Produkt zu konvertieren; verschachtelte Ausnahme ist java.lang.IllegalArgumentException: Wert kann nicht vom Typ umwandeln [java.lang.String] auf die gewünschte Art [beans.Product] für Immobilien Produkt: keine passenden Editoren oder Umwandlung Strategie gefunden

im Errors errors-Objekt, noch bevor mein DetailProductValidator mit der validate-Methode beginnt, zu validieren.

Ich verstehe nicht, warum Spring das tut. Ich habe kein Eingabefeld, das direkt der Produkteigenschaft/dem Objekt zugeordnet ist. Ich verwende nur die Eigenschaften des Produktobjekts in der JSP. Zum Beispiel verwende ich:

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

aber ich benutze nie:

<form:input path="product"/> 

Kann jemand bitte erklären, warum dies geschieht? Und vielleicht informieren Sie mich über eine einfache Lösung?

Die Bohne Konfiguration für den Controller ist:

<!-- 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> 

Das Trägerobjekt für den DetailProductFormController ist:

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 
} 

Wenn Sie einige andere Informationen benötigen, stelle ich. Ich benutze Frühling 2.5.5.

Mit freundlichen Grüßen,
Despot

EDIT1 (aufgrund Anfrage von 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 (aufgrund JacobM Wunsch): Dies ist mein Validator:

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."); 
     } 
    } 
} 

Wenn ich die Zeile erreichen DetailProductBackingObject detailProductBackingObject = Ich habe bereits den Fehler.
Die Konvertierung der Anforderungsparameter in die Eigenschaften des Sicherungsobjekts erfolgt in http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/web/servlet/mvc/BaseCommandController.html.Dies ist, was Frühling sagt über die Umwandlung:

Bestücken Anfrage mit Hilfe von Parametern und PropertyEditors: Auf eine Anforderung empfängt, jede BaseCommandController versuchen wird, den Befehl Objekt unter Verwendung der Anforderungsparameter zu füllen. Dies geschieht mit der typischen und bekannten JavaBeans-Eigenschaft Notation. Wenn ein Anforderungsparameter mit dem Namen 'firstName' vorhanden ist, versucht das Framework setFirstName ([Wert]) aufzurufen, wobei der Wert des Parameters übergeben wird. Verschachtelte Eigenschaften werden natürlich unterstützt. Zum Beispiel führt ein Parameter namens 'address.city' zu einem getAddress(). SetCity ([value]) Aufruf auf der Befehlsklasse.

Es ist wichtig zu wissen, dass Sie nicht auf String-Argumente in Ihre JavaBeans beschränkt sind. Mit dem PropertyEditor-Begriff, wie von der java.beans-Paket geliefert, werden Sie in der Lage, Strings zu Objekten und umgekehrt umzuwandeln. Zum Beispiel setLocale (Locale loc) ist perfekt möglich, dass ein Anforderungsparameter namens locale einen Wert von en hat, so lange , wie Sie den entsprechend Property im Controller registrieren (siehe initBinder() für weitere Informationen über dass . Materie

Validierer. Nachdem die Steuerung den Befehl Objekt mit Parametern von der Anforderung erfolgreich besiedelt hat, wird es alle konfigurierten Validierer verwenden, um das Objekt zu validieren Validation Ergebnisse werden in einem Errors gestellt werden Objekt, das in einer View verwendet werden kann, um Eingabeprobleme zu rendern.

+0

Eigentlich, was ich gerne sehen würde, ist die Controller-Methode, die das Formular übermittelt wird. Dies ist der Punkt, an dem Spring wahrscheinlich versucht, eine Formularübergabe, die aus Strings besteht, in ein tatsächliches Produktobjekt umzuwandeln. –

+0

Hi JacobM, da ich die Request-Parameter nicht selbst in die Eigenschaften des Backing-Objekts umwandle (ich habe dafür keine dedizierte Methode/Klasse), kann ich das nicht für Sie bereitstellen. Dies wird von Spring gemacht und die einzige Erklärung, die wir haben, ist diejenige, die ich in EDIT2 geschrieben habe. Aus diesem Grund kann ich nicht erkennen, warum Spring einen String in die Produkteigenschaft des Sicherungsobjekts konvertieren möchte. Irgendwelche Gedanken? – despot

+0

Versuchen Sie, die Anfrage zu erhalten, wie sie eingereicht wird (Firebug ist ein guter Weg) und alle Parameter zu betrachten. Gibt es einen Parameter namens "Produkt"? –

Antwort

4

Da ich nichts falsch mit der Form, der einzig mögliche Grund kann ich mich vorstellen sehen kann, ist, dass Sie einen Parameter haben product in der URL Ihrer Formularseite genannt.

Wenn ja, können Sie Ihre URLs ändern oder DataBinder.setDisallowedFields() verwenden, um den Versuch zu deaktivieren, diesen Parameter zu binden.

+0

Hallo axtavt, so wahr !!! Ich habe vergessen, dass der Client diese Werte in der Anfrage sendet ... und über das Denken außerhalb der Box reden! Vielen Dank!!! PS: Ich habe bereits die Controllerlogik geändert, um mit den Eigenschaften des Produkts zu arbeiten, anstatt das Produktobjekt direkt zu verwenden, aber ich wollte so wissen, was mit Spring vor sich ging ... Ich denke, ich werde es jetzt ändern;) – despot