【问题标题】:Spring tag <form:option> not working with Spring Data DomainClassConverter?Spring 标签 <form:option> 不能与 Spring Data DomainClassConverter 一起使用?
【发布时间】:2012-09-08 01:26:12
【问题描述】:

我正在使用 Spring MVC 和 Spring Data,并且还配置了 Spring Data 的 DomainClassConverter 以自动将 String id 转换为适当的 Domain 类。

我现在正在使用以下标签实现 Order to Customer 参考:

<form:select path="customer">
    <form:option value="" label="Select" />
    <form:options items="${customers}" itemValue="id" />
</form:select>

生成给定的 HTML:

<select id="customer" name="customer" class="span6">
    <option value="">Select</option>
    <option value="1">Customer A</option>
    <option value="2">Customer B</option>
    <option value="3">Customer C</option>
</select>

提交帖子时,例如客户 A 选择我得到一个例外,如:

org.apache.jasper.JasperException: org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.lang.String to type @javax.validation.constraints.NotNull @javax.persistence.ManyToOne nl.kapsalonreflection.domain.Customer for value ''; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: The given id must not be null!; nested exception is java.lang.IllegalArgumentException: The given id must not be null!

这根本没有意义,因为收到的值应该是 1 而不是 ''。 我还调试了收到的请求参数,它只包含 customer=1(如预期的那样)

请注意,InvalidDataAccessApiUsageException 来自 Spring Data 的 DomainClassConverter,如果我删除此转换器,问题就不会再发生了。

我还调试了DomainClassConverter,我可以看到它试图覆盖两次。 首先使用字符串值 1(如预期的那样),然后使用空字符串进行另一个调用,导致异常。

但它变得更奇怪了......

当我用纯 html 元素 &lt;option value=""&gt;Select&lt;/option&gt; 替换 &lt;form:option value="" label="Select" /&gt; 时,不会发生异常,因此只有 1 次调用使用字符串 1 的转换方法。 奇怪的是&lt;form:option value="" label="Select" /&gt;&lt;option value=""&gt;Select&lt;/option&gt; 产生相同的html 输出...

我无法解释这种行为......虽然我似乎有一个使用普通 html 元素的“解决方法”,但我想知道是什么导致了这个问题。

【问题讨论】:

    标签: spring spring-mvc spring-data spring-data-jpa


    【解决方案1】:

    注意org.apache.jasper.JasperException 表示异常发生在JSP 渲染期间,而不是在数据绑定期间。这与异常依赖于&lt;form:option value="" label="Select" /&gt;这一事实是一致的——它在回发后呈现表单时正在处理此标记时被抛出。

    您观察到的行为可以解释如下:为了确定其选定状态&lt;form:option&gt; 尝试将其值与绑定到&lt;form:select&gt; 的字段的值进行比较。如果绑定字段的值为null&lt;form:option&gt; 只是将其值与null 进行比较,这就是为什么在初始表单呈现期间不会出现此异常的原因。否则,&lt;form:option&gt; 会尝试将其&lt;value&gt; 转换为绑定字段的类型,而value = "" 在这一步会导致异常。

    因此,您应该使用null 而不是空字符串作为“未选择选项”值:

    <form:option value="${null}" label="Select" /> 
    

    【讨论】:

    • value="${null}" 成功了。非常感谢您的帮助,因为我完全陷入困境并且走错了路。仍然无法解释为什么 DomainClassConverter 试图转换两次。一次是实际值,一次是空值...
    【解决方案2】:

    在这种情况下,您可能需要考虑附加一个属性编辑器,因为如果我看到代码&lt;form:options items="${customers}" itemValue="id" /&gt;,您就是直接将客户列表附加到选项中。我认为它自动获取 toString 并显示“客户 A”、“客户 B”等。理想情况下,您可能需要在 form:options 标记中使用 itemLabel,或者您可能需要注册一个属性编辑器并将其附加到 initBinder http://static.springsource.org/spring/docs/2.5.x/reference/validation.html#beans-beans-conversion

    【讨论】:

      猜你喜欢
      • 2012-09-07
      • 1970-01-01
      • 2020-10-31
      • 2014-03-10
      • 2014-10-21
      • 2018-11-12
      • 1970-01-01
      • 2014-12-20
      • 2019-03-07
      相关资源
      最近更新 更多