当前位置: 首页 > 知识库问答 >
问题:

Spring表单:提交大型对象列表时的BindException

朱越
2023-03-14

我有一个表单,它显示了DataTables中的几个对象列表。通过此表单,管理员用户可以定义特定用户对这些对象的权限。

例如,这是product permissions 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个错误

对象“PermisOS List”中字段“PermisOS Producto[137].Producto.idProd”上的字段错误:拒绝值[];代码参数[org.springframework.context.support.defaultmessageSourceSolvable:代码[PermisosList.PermisosProducto[137].Producto.idprod,PermisosProducto[137].Producto.idprod];参数[];默认消息[PermisosProducto[137].Producto.idprod]];默认消息[无法将“java.lang.String”类型的属性值转换为属性“Permisos Producto[137].Producto.idProd”所需的类型“int”;嵌套异常为java.lang.NumberFormatException:对于输入字符串:“”]

对象“PermisOS List”中字段“PermisOS Producto[338]”得字段错误.PermisO“:拒绝值[];代码[TypeMisMatch.PermisosList.PermisosProducto[338].Permiso,TypeMisMatch.PermisosProducto.Permiso,TypeMisMatch.PermisosProducto[338].Permiso,TypeMisMatch.PermisosProducto.Permiso,TypeMisMatch.Permiso,TypeMisMatch.int,TypeMisMatch];参数[org.springframework.context.support.defaultmessageSourceSolvable:代码[PermisosList.PermisosProducto[338].Permiso,PermisosProducto[338].Permiso];参数[];默认消息[PermisosProducto[338].Permiso]];默认消息[无法将“java.lang.String”类型的属性值转换为属性“PermisOS Producto[338].Permiso”所需的类型“int”;嵌套异常为java.lang.NumberFormatException:对于输入字符串:“”]

对象“Permisos List”中字段“Permisos Producto[573]”得字段错误.Permiso“:拒绝值[];代码[TypeMisMatch.PermisosList.PermisosProducto[573].Permiso,TypeMisMatch.PermisosProducto.Permiso,TypeMisMatch.PermisosProducto[573].Permiso,TypeMisMatch.PermisosProducto.Permiso,TypeMisMatch.Permiso,TypeMisMatch.int,TypeMisMatch];参数[org.springframework.context.support.defaultmessageSourceSolvable:代码[PermisosList.PermisosProducto[573].Permiso,PermisosProducto[573].Permiso];参数[];默认消息[PermisosProducto[573].Permiso]];默认消息[无法将“java.lang.String”类型的属性值转换为属性“PermisOS Producto[573].Permiso”所需的类型“int”;嵌套异常为java.lang.NumberFormatException:对于输入字符串:“”]

对象“PermisOS List”中字段“PermisOS Producto[808]”得字段错误.PermisO“:拒绝值[];代码[TypeMisMatch.PermisosList.PermisosProducto[808].Permiso,TypeMisMatch.PermisosProducto.Permiso,TypeMisMatch.PermisosProducto[808].Permiso,TypeMisMatch.PermisosProducto.Permiso,TypeMisMatch.Permiso,TypeMisMatch.int,TypeMisMatch];参数[org.springframework.context.support.defaultmessageSourceSolvable:代码[PermisosList.PermisosProducto[808].Permiso,PermisosProducto[808].Permiso];参数[];默认消息[PermisosProducto[808].Permiso]];默认消息[无法将“java.lang.String”类型的属性值转换为属性“PermisOS Producto[808].Permiso”所需的类型“int”;嵌套异常为java.lang.NumberFormatException:对于输入字符串:“”]

我已经检查了那些索引处的信息是正常的,所以任何地方都没有空字段(那么为什么一旦提交了数据就会有空字段呢?)。我还注意到这些指数并不总是相同的。如果我重新启动tomcat或几分钟后重试,错误中的索引可能会有所不同。并且只发生在具有至少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);
}

现在发生的情况是,那些有空字符串的索引现在有一个'null'值(由于CustomEditor)。正如我所说的,我在提交表单之前检查了信息,我可以看到列表中的所有对象都是正常的,没有一个元素带有空字段。

那么为什么Spring会在列表相当大的情况下对数据这么做呢?它似乎是对随机索引做的...

编辑二:这是TOMCAT的一期!我在Pivotal tc服务器(V3.1)上部署了binder.SetAutoGrowCollectionLimit(2048);解决方案,没有任何异常、空字符串或NULL。功能齐全。

所以问题出在tomcat(V8.0)配置上。有人知道这件事吗?

编辑3:我接受@angcap的回答,因为它确实解决了我最初的问题。按照他说的去做,就避免了双索引。

共有1个答案

宗政法
2023-03-14

您似乎为数字字段idprodpermiso张贴了空字符串。检查已发布的数据或尝试注册CustomNumberEditor,允许在控制器中使用@InitBinder使用empyValues。

 类似资料:
  • 我有一个数据模型是这样的: 当我在表中添加新行并更新表中现有行时。在提交表单时,我获得了控制器中现有行的更新值,但我没有获得新添加的行作为控制器中的新元素。获取对象中新添加的元素所需做的操作。

  • 基本上,表单提交的表单支持对象总是空的。有人知道为什么会这样吗? 我有一个简单的控制器,显示设备列表。可以选择设备并对其应用功能。这是控制器: 设备模型对象是一个Hibernate实体: 并通过DeviceMapper映射到DeviceViewModel DeviceViewModel: 以及设备标签: 现在是DeviceCommand,它是我的表单支持对象: 最后是devices.html页面的

  • 下面是MultistepForm的代码。我已经实现了一个多步骤表单功能,所以这里一切都很好,只是问题是在这个表单中,我在最后一步有一个预览页面,所以当我点击提交按钮时,表单正在消失,按钮正在顶部移动。所以如果有人能帮我请。

  • 我在一个基于Spring的Web应用程序(版本4.1.6。RELEASE,Spring Security 4.0.0。RELEASE)中工作,我收到错误(POST方法)。根据Spring的留档“Spring Security自动为任何

  • 大家要切记这一点: 在任何 Single Page App中,js代码都不会产生 一个传统意义的form表单提交!(这会引起整个页面的刷新) 所以,我们往往用事件来实现.(桌面开发思维) 假设,我们在远程有个接口,可以接受别人的留言: URL: http://siwei.me/interface/blogs/add_comment 参数: content: 留言的内容. 请求方式: POST 返回

  • 获取Form变量 通过Action的如下方法可以获取变量: GetSlice GetString GetInt GetBool GetFloat GetFile GetForm 自动映射 通常我们通过http.Request.Form来获得从用户中请求到服务器端的数据,这些数据一般都是采用name,value的形式提交的。xweb默认支持自动将这些变量映射到Action的成员中,并且这种映射支持子