2010-12-06 59 views
4

我收到異常爲什麼我得到IllegalArgumentException在Spring中無法將String類型的值轉換爲所需類型Product?

無法屬性值轉換 類型的[java.lang.String中]所需 類型[beans.Product用於屬性 產物;嵌套的異常是 java.lang.IllegalArgumentException異常: 無法轉換 類型的值[java.lang.String中]所需類型 [beans.Product用於屬性產品: 沒有匹配的編輯器或轉換 策略發現

甚至在我的DetailProductValidator開始通過驗證方法驗證之前,Errors errors對象中。

我不明白爲什麼春天那麼做。我沒有任何直接映射到產品屬性/對象的輸入字段。我只是在jsp中使用產品對象的屬性。比如,我用:

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

,但我從來沒有使用:

<form:input path="product"/> 

任何人都可以請解釋爲什麼出現這種情況?也許告訴我一個簡單的解決方案?

爲控制器的bean配置爲:

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

爲DetailProductFormController的支持對象是:

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 
} 

如果你需要其他的一些信息,我會提供。我正在使用Spring 2.5.5。

親切的問候,
暴君

EDIT1由於從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由於JacobM要求): 這是我的驗證者:

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

當我到達線DetailProductBackingObject detailProductBackingObject =我已經有錯誤。
將請求參數轉換爲後臺對象的屬性發生在http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/web/servlet/mvc/BaseCommandController.html。這就是春說,關於轉換:

填充使用請求參數 與屬性:當接收到一個請求 ,任何BaseCommandController 將試圖填補使用請求參數的命令 對象。 這是使用典型的和 着名的JavaBeans屬性 表示法完成的。當存在名爲'firstName'的請求參數 時, 框架將嘗試呼叫 setFirstName([value])傳遞參數的 值。當然支持嵌套 屬性。 例如,一個名爲 'address.city'的參數將在 命令類中產生 getAddress()。setCity([value])調用。

重要的是要認識到,您的 不限於您的JavaBeans中的 中的字符串參數。使用 java.beans包提供的 PropertyEditor-notion,您將是 能夠將字符串轉換爲對象 ,反之亦然。例如 的setLocale(區域設置LOC)是完全 可能命名爲 區域en的值,請求參數,只要 你註冊在控制器適當 屬性編輯器(見 initBinder()的詳細信息, 那。事項

校驗:該控制器具有 成功地填充命令 對象與來自 請求參數後,它會使用任何配置 驗證來驗證對象驗證 結果將被放入 錯誤對象,可以在 視圖中使用,以呈現任何輸入問題。

+0

其實,我想看到的是表單提交給控制器的方法。這是Spring可能嘗試將包含字符串的表單提交轉換爲實際Product對象的地方。 – 2010-12-06 17:53:32

+0

嗨,JacobM,因爲我自己並沒有將請求參數轉換爲後備對象的屬性(我沒有專門的方法/類),所以我無法爲你提供這個。這是由Spring完成的,唯一的解釋是我在EDIT2中編寫的那個。從這裏我看不出Spring爲什麼要將某些字符串轉換爲後備對象的Product屬性。有什麼想法嗎? – despot 2010-12-06 18:46:15

回答

4

由於我無法看到表單有什麼問題,我可以想象的唯一可能的原因是您的表單頁面的URL中有一個名爲product的參數。

如果是這樣,您可以更改您的URL或使用DataBinder.setDisallowedFields()禁用嘗試綁定該參數。

相關問題