Spring mvc web表单重新加载时属性值丢失(null/empty)
使用SpringMVC3.0.5时,我遇到了一个奇怪的(几乎是零星的)数据绑定错误。 在应用程序的一个页面中,使用了一个具有一些基本值(很少的字符串和长字符串)和两个列表(让我们将它们命名为a和B)的模型bean。列表显示在两个表中(使用displaytag)。用户可以编辑一些原语值并从中提交,以显示更新的数据(重新显示相同的页面)。列表数据存储在页面中的隐藏输入字段中 问题是,有时一个隐藏字段在POST/display循环中丢失。Java值变为null,在HTML中为“变为值=”“。(一个长类型和一个布尔值) 到目前为止,它只发生在model属性中的两组特定数据值上。在一种情况下,一个值在第N次迭代(N约为3或4次)中消失,而在另一种情况下,它发生在第一次发布时。 在许多其他数据集中,没有发现任何问题。就像是未初始化的变量使用、未同步的跨线程数据访问或类似情况一样 问题是:Spring mvc web表单重新加载时属性值丢失(null/empty),spring-mvc,apache-commons-fileupload,Spring Mvc,Apache Commons Fileupload,使用SpringMVC3.0.5时,我遇到了一个奇怪的(几乎是零星的)数据绑定错误。 在应用程序的一个页面中,使用了一个具有一些基本值(很少的字符串和长字符串)和两个列表(让我们将它们命名为a和B)的模型bean。列表显示在两个表中(使用displaytag)。用户可以编辑一些原语值并从中提交,以显示更新的数据(重新显示相同的页面)。列表数据存储在页面中的隐藏输入字段中 问题是,有时一个隐藏字段在POST/display循环中丢失。Java值变为null,在HTML中为“变为值=”“。(一个长类
- 这听起来像是已知的臭虫吗
- 如何进行?一步一步调试?去哪里看
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<form:form id="form" method="post" modelAttribute="myRequest" action="spremembaUporabnika" enctype="multipart/form-data">
<display:table id="table1" name="myRequest.listA" decorator="si.comtrade.vs.web.decorators.users.UserRightsDecorator">
<display:setProperty name="paging.banner.all_items_found" value=""/>
<display:setProperty name="paging.banner.onepage" value=""/>
<display:column title="Column1">
<c:out value="${myRequest.listA[table1_rowNum-1].orgUnitName}"/>
<form:hidden path="listA[${table1_rowNum-1}].string1" id="string1[${table1_rowNum-1}]"/>
<form:hidden path="listA[${table1_rowNum-1}].long1" id="long1[${table1_rowNum-1}]"/>
<form:hidden path="listA[${table1_rowNum-1}].long2" id="long2[${table1_rowNum-1}]"/>
<form:hidden path="listA[${table1_rowNum-1}].string2" id="string2[${table1_rowNum-1}]"/>
</display:column>
<display:column escapeXml="true" property="prop2" title="Column2" />
...
</display:table>
...
模型类:
public class MyRequest {
private List<TypeA> listA = new AutoPopulatingList<TypeA>(TypeA.class);
private List<TypeB> listB = new AutoPopulatingList<TypeB>(TypeB.class);
// ... other fields and getters/setters omitted
}
public class TypeA {
Long long1, long2; // <---- one of these loses the value on POST/reload
String string1, string2;
// ... other fields and getters/setters omitted
}
公共类MyRequest{
private List listA=新的自动人口英语(TypeA.class);
private List listB=新的AutopopulationGlist(类型B.class);
//…省略了其他字段和getter/setter
}
公共类A型{
Long long1,long2;//显然这是commons-fileupload-1.2中org.apache.commons.fileupload.MultipartStream中的一个bug
方法public int read(byte[]b,int off,int len)(第878行)中的代码尝试读取参数值,但当缓冲区中没有可用数据(由available()检查)时,它调用makeAvailable()从HTTP请求流中读取更多数据。这可能返回0、1或类似的几个字节,这些字节不足以包含分隔符字符串,因此仍然有0字节可用(),并且读取方法使用-1退出,而不是从HTTP请求流中读取更多数据
供参考:
/* this is line 877 */
public int read(byte[] b, int off, int len) throws IOException {
if (closed) {
throw new FileItemStream.ItemSkippedException();
}
if (len == 0) {
return 0;
}
int res = available();
if (res == 0) {
res = makeAvailable();
if (res == 0) {
return -1;
}
}
res = Math.min(res, len);
System.arraycopy(buffer, head, b, off, res);
head += res;
total += res;
return res;
}
这是一个已知的错误:
已在版本1.2.1中修复
/* this is line 877 */
public int read(byte[] b, int off, int len) throws IOException {
if (closed) {
throw new FileItemStream.ItemSkippedException();
}
if (len == 0) {
return 0;
}
int res = available();
if (res == 0) {
res = makeAvailable();
if (res == 0) {
return -1;
}
}
res = Math.min(res, len);
System.arraycopy(buffer, head, b, off, res);
head += res;
total += res;
return res;
}