我有这种形式,它显示了数据表中的对象的几个列表。通过此表单,管理员用户可以定义特定用户对这些对象的权限。
例如,这是产品权限dataTable的jsp代码:
<sf:form action="${action}" class="form-horizontal" method="post" modelAttribute="permisosList" enctype="multipart/form-data" >
...
<table class="table table-striped table-bordered table-hover" id="tabla_permisos6">
<thead>
<tr>
<th><%=Languages.getString("Producto")%></th>
<th><%=Languages.getString("Permiso")%></th>
</tr>
</thead>
<tbody>
<c:forEach items="${permisosList.permisosProducto}" var="permiso" varStatus="counter">
<tr>
<sf:input path="permisosProducto[${counter.index}].producto.idProd" type="hidden"/>
<td style="vertical-align:middle;"><c:out value="${permiso.producto.nombre}"/></td>
<td align="center">
<sf:select class="form-control" path="permisosProducto[${counter.index}].permiso" type="number">
<sf:option value="0">
<c:out value="No visible" />
</sf:option>
<sf:option value="1">
<c:out value="Visible" />
</sf:option>
<sf:option value="2">
<c:out value="Descarga" />
</sf:option>
</sf:select>
</td>
</tr>
</c:forEach>
</tbody>
</table>
...
其中一些列表内部有成百上千个对象,因此,当我提交表单时,我得到了Spring BindException:
org.springframework.validation.BindException:org.springframework.validation.BeanPropertyBindingResult:4个错误
字段“ permisosProducto [137] .producto.idProd”上的对象“ permisosList”中的字段错误:拒绝的值[];代码[typeMismatch.permisosList.permisosProducto [137] .producto.idProd,typeMismatch.permisosList.permisosProducto.producto.idProd,typeMismatch.permisosProducto [137] .producto.idProd,类型Mismatch.permisosProducto.producto.idProd,typeMismatchid。 int,typeMismatch];参数[org.springframework.context.support.DefaultMessageSourceResolvable:代码[permisosList.permisosProducto [137] .producto.idProd,permisosProducto [137] .producto.idProd];参数[];默认消息[permisosProducto [137] .producto.idProd]];默认消息[未能将属性'permisosProducto [137] .producto.idProd'的类型'java.lang.String'的属性值转换为必需的类型'int';嵌套的异常是java.lang.NumberFormatException:对于输入字符串:“”]
字段“ permisosProducto [338] .permiso”上的对象“ permisosList”中的字段错误:拒绝的值[];代码[typeMismatch.permisosList.permisosProducto [338] .permiso,typeMismatch.permisosList.permisosProducto.permiso,typeMismatch.permisosProducto [338] .permiso,typeMismatch.permisosProducto.permiso,typeMismatch.permiso,typeMismatch.int,typeMismatch.int,参数[org.springframework.context.support.DefaultMessageSourceResolvable:代码[permisosList.permisosProducto [338] .permiso,permisosProducto [338] .permiso];参数[];默认消息[permisosProducto [338] .permiso]];默认消息[未能将属性'permisosProducto [338] .permiso'的类型'java.lang.String'的属性值转换为必需的类型'int';嵌套的异常是java.lang.NumberFormatException:对于输入字符串:“”]
字段“ permisosProducto [573] .permiso”上的对象“ permisosList”中的字段错误:拒绝的值[];代码[typeMismatch.permisosList.permisosProducto [573] .permiso,typeMismatch.permisosList.permisosProducto.permiso,typeMismatch.permisosProducto [573] .permiso,typeMismatch.permisosProducto.permiso,typeMismatch.permiso,typeMismatch.int,typeMismatch.int,参数[org.springframework.context.support.DefaultMessageSourceResolvable:代码[permisosList.permisosProducto [573] .permiso,permisosProducto [573] .permiso];参数[];默认消息[permisosProducto [573] .permiso]];默认消息[未能将属性'permisosProducto [573] .permiso'的类型'java.lang.String'的属性值转换为所需的类型'int';嵌套的异常是java.lang.NumberFormatException:对于输入字符串:“”]
字段“ permisosProducto [808] .permiso”上的对象“ permisosList”中的字段错误:拒绝的值[];代码[typeMismatch.permisosList.permisosProducto [808] .permiso,typeMismatch.permisosList.permisosProducto.permiso,typeMismatch.permisosProducto [808] .permiso,typeMismatch.permisosProducto.permiso,typeMismatch.permiso,typeMismatch.int,typeMismatch.int,参数[org.springframework.context.support.DefaultMessageSourceResolvable:代码[permisosList.permisosProducto [808] .permiso,permisosProducto [808] .permiso];参数[];默认消息[permisosProducto [808] .permiso]];默认消息[无法将类型'java.lang.String'的属性值转换为属性'permisosProducto [808] .permiso'的必需类型'int';嵌套的异常是java.lang.NumberFormatException:对于输入字符串:“”]
我已经检查了这些索引处的信息是否正常,因此任何地方都没有空字段(然后为什么一旦提交数据后又有空字段?)。我还注意到,这些索引并不总是相同的。也许如果我重新启动tomcat或稍后重试minut,则错误中的索引会有所不同。并且仅在具有至少200个以上对象的列表中发生。并且在到达控制器之前会引发异常。
这是我的PermisoList类:
public class PermisoList {
List<PermisoProductoForm> permisosProducto;
List<PermisoCarpetaForm> permisosCarpeta;
List<PermisoTipoDocForm> permisosTipoDoc;
List<PermisoAgenteClienteForm> permisosAgenteCliente;
List<PermisoIdiomaForm> permisosIdioma;
List<PermisoPaisForm> permisosPais;
List<PermisoEmpresaForm> permisosEmpresa;
List<PermisoUsuarioProductoForm> permisosUsuarioProducto;
...
}
我的PermisoProductoForm类:
public class PermisoProductoForm {
private Producto producto;
private int permiso;
...
}
而我的Producto课:
@Entity
@Table(name = "Producto")
public class Producto {
@Id
@GeneratedValue
private int idProd;
private String codigo;
private String nombre;
private String marca;
private boolean activo;
@ManyToOne
@JoinColumn(name = "idFamilia")
private Familia familia;
@OneToMany(mappedBy = "producto", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<Documento> documentacion;
@ManyToOne
@JoinColumn(name = "idEmpresa")
private Empresa empresa;
@OneToMany(mappedBy = "primaryKey.producto", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<PermisoUsuarioProducto> permisosProducto;
@OneToMany(mappedBy = "productoRelacionado", fetch = FetchType.LAZY)
private List<TemaForo> temasForo;
...
}
另外,我已经尝试了一些解决方案,例如将以下代码添加到控制器中:
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.setAutoGrowCollectionLimit(2048);
}
或在jsp代码的form标记内添加
enctype="multipart/form-data"
。有谁知道为什么会这样或知道如何解决这个问题?我现在100%陷入困境。
编辑:我已经完成了@angcap的回答(将int更改为Integer类型,并在initBinder方法中添加CustomEditor),现在不再抛出此BindException了。这样就达到了控制器。
现在发生的是那些具有空字符串的索引现在具有“空”值(由于CustomEditor)。就像我说的那样,我在提交表单之前已经检查了信息,我可以看到列表中的所有对象都可以,没有一个带空字段的元素。
那么,当列表很大时,为什么Spring会对数据这样做呢?它似乎可以对随机索引进行处理...
编辑2:这是一个TOMCAT问题!我已经部署在Pivotal tc Server(v3.1)上,并且使用
binder.setAutoGrowCollectionLimit(2048);
解决方案,可以正常工作,没有任何异常,空字符串或null。功能齐全。因此问题出在tomcat(v8.0)配置中。有人对这个有了解吗?
编辑3:我接受@angcap答案,因为它确实解决了我的最初问题。通过执行他所说的操作,可以避免BindException。
最佳答案
似乎您正在为数字字段idProd
和permiso
发布空字符串。检查发布的数据,或尝试使用@initBinder在控制器中注册CustomNumberEditor以允许empyValues。