Spring Webflow 2.4.5 multipart/form-data 绑定问题
Spring Webflow 2.4.5 multipart/form-data binding problems
我为项目配置了多部分解析器:
@EnableWebMvc
@ComponentScan({"com.dg"})
@Configuration
@SuppressWarnings("deprecation")
public class AppConfig extends AbstractFlowConfiguration {
@Bean
public CommonsMultipartResolver fileResolver() {
CommonsMultipartResolver cr = new CommonsMultipartResolver();
cr.setDefaultEncoding("UTF-8");
cr.setMaxUploadSize(26214400);
return cr;
}
}
我正在使用可序列化对象作为模型:
public class NewRequestModel implements Serializable {
private static final long serialVersionUID = -5372803991673351564L;
private String entry;
private transient MultipartFile attachment;
... // getters and setters
}
当页面加载时,我初始化模型:
网络流量
<var name="requestModel" class="com.dg.model.request.NewRequestModel" />
<on-start>
<evaluate expression="newRequestAction.initTestRequest" />
</on-start>
操作
public Event initTestRequest(RequestContext context) {
NewRequestModel model = (NewRequestModel)context.getFlowScope().get("requestModel");
if (model==null) {
model = new NewRequestModel();
}
context.getFlowScope().put("requestModel", model);
return new Event(this, "DONE");
}
我绑定 JSP 中的值:
<form:form id="actionForm" method="POST" modelAttribute="requestModel" enctype="multipart/form-data">
<div class="panel-heading">
Test Request
</div>
<div class="panel-body">
<div class="form-group">
<form:input path="entry" />
</div>
<div class="form-group">
<form:input type="file" path="attachment" />
</div>
<div>
<button type="button" class="btn btn-primary" onclick="app.submitEvent({formSelector: '#actionForm',event: 'submitAndValidate'});">
Submit Request
</button>
</div>
</div>
</form:form>
单击按钮时,表单随事件一起提交 "submitAndValidate"
<view-state id="start" view="request/test/test-request" model="requestModel">
<transition on="submitAndValidate" to="submitAndValidate" />
</view-state>
<action-state id="submitAndValidate">
<evaluate expression="newRequestAction.testRequest" />
<transition to="start" />
</action-state>
当我调试 Action class、testRequest 方法时,模型不保留随表单提交的值。
public Event testRequest(RequestContext context) {
NewRequestModel model = (NewRequestModel)context.getFlowScope().get("requestModel");
String entry= model.getEntry();
MultipartFile file = model.getAttachment();
if (entry==null) {
// is null when enctype is included on form
// is populated when enctype is not included on form
}
if (file==null) {
// always null for some reason
}
return new Event(this, "DONE");
}
如果我从表单中删除 enctype="multipart/form-data",则绑定适用于 "entry" 变量。当然,这不允许上传文件。所以我需要能够在表单中包含 enctype。
我已经检查了这个并查找了答案并阅读了指南,但我只是不明白为什么会失败。感谢您帮助我找到有问题的 configuration/code.
尝试向您的表单添加操作(crsf 属性是可选的):
<form:form action="${flowExecutionUrl}&${_csrf.parameterName}=${_csrf.token}" modelAttribute="requestModel" enctype="multipart/form-data">
并使用简单的输入:
<input type="file" name="attachment" id="attachment"/>
和一个简单的提交:
<input type="submit" id="submitAndValidate" name="_eventId_ submitAndValidate" value="Submit Request">
问题出在我的 MultipartResolver bean 配置中。 Spring 正在专门寻找名为 "multipartResolver." 的 bean,因此我有 2 个选项来解决这个问题:
选项 1 - 在 @Bean 注释中指定名称
@Bean(name="multipartResolver")
public CommonsMultipartResolver fileResolver() {
CommonsMultipartResolver cr = new CommonsMultipartResolver();
cr.setDefaultEncoding("UTF-8");
cr.setMaxUploadSize(26214400);
return cr;
}
选项 2 - 重命名方法
@Bean
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver cr = new CommonsMultipartResolver();
cr.setDefaultEncoding("UTF-8");
cr.setMaxUploadSize(26214400);
return cr;
}
对于大多数人来说,上述更改可能会解决问题。但是,由于进行上述更改后出现 ClassNotFoundException 错误,我还需要将 Apache Commons IO 添加到我的项目中。
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
有了这些更新,表单现在可以正确绑定了。我的问题已解决。
我为项目配置了多部分解析器:
@EnableWebMvc
@ComponentScan({"com.dg"})
@Configuration
@SuppressWarnings("deprecation")
public class AppConfig extends AbstractFlowConfiguration {
@Bean
public CommonsMultipartResolver fileResolver() {
CommonsMultipartResolver cr = new CommonsMultipartResolver();
cr.setDefaultEncoding("UTF-8");
cr.setMaxUploadSize(26214400);
return cr;
}
}
我正在使用可序列化对象作为模型:
public class NewRequestModel implements Serializable {
private static final long serialVersionUID = -5372803991673351564L;
private String entry;
private transient MultipartFile attachment;
... // getters and setters
}
当页面加载时,我初始化模型:
网络流量
<var name="requestModel" class="com.dg.model.request.NewRequestModel" />
<on-start>
<evaluate expression="newRequestAction.initTestRequest" />
</on-start>
操作
public Event initTestRequest(RequestContext context) {
NewRequestModel model = (NewRequestModel)context.getFlowScope().get("requestModel");
if (model==null) {
model = new NewRequestModel();
}
context.getFlowScope().put("requestModel", model);
return new Event(this, "DONE");
}
我绑定 JSP 中的值:
<form:form id="actionForm" method="POST" modelAttribute="requestModel" enctype="multipart/form-data">
<div class="panel-heading">
Test Request
</div>
<div class="panel-body">
<div class="form-group">
<form:input path="entry" />
</div>
<div class="form-group">
<form:input type="file" path="attachment" />
</div>
<div>
<button type="button" class="btn btn-primary" onclick="app.submitEvent({formSelector: '#actionForm',event: 'submitAndValidate'});">
Submit Request
</button>
</div>
</div>
</form:form>
单击按钮时,表单随事件一起提交 "submitAndValidate"
<view-state id="start" view="request/test/test-request" model="requestModel">
<transition on="submitAndValidate" to="submitAndValidate" />
</view-state>
<action-state id="submitAndValidate">
<evaluate expression="newRequestAction.testRequest" />
<transition to="start" />
</action-state>
当我调试 Action class、testRequest 方法时,模型不保留随表单提交的值。
public Event testRequest(RequestContext context) {
NewRequestModel model = (NewRequestModel)context.getFlowScope().get("requestModel");
String entry= model.getEntry();
MultipartFile file = model.getAttachment();
if (entry==null) {
// is null when enctype is included on form
// is populated when enctype is not included on form
}
if (file==null) {
// always null for some reason
}
return new Event(this, "DONE");
}
如果我从表单中删除 enctype="multipart/form-data",则绑定适用于 "entry" 变量。当然,这不允许上传文件。所以我需要能够在表单中包含 enctype。
我已经检查了这个并查找了答案并阅读了指南,但我只是不明白为什么会失败。感谢您帮助我找到有问题的 configuration/code.
尝试向您的表单添加操作(crsf 属性是可选的):
<form:form action="${flowExecutionUrl}&${_csrf.parameterName}=${_csrf.token}" modelAttribute="requestModel" enctype="multipart/form-data">
并使用简单的输入:
<input type="file" name="attachment" id="attachment"/>
和一个简单的提交:
<input type="submit" id="submitAndValidate" name="_eventId_ submitAndValidate" value="Submit Request">
问题出在我的 MultipartResolver bean 配置中。 Spring 正在专门寻找名为 "multipartResolver." 的 bean,因此我有 2 个选项来解决这个问题:
选项 1 - 在 @Bean 注释中指定名称
@Bean(name="multipartResolver")
public CommonsMultipartResolver fileResolver() {
CommonsMultipartResolver cr = new CommonsMultipartResolver();
cr.setDefaultEncoding("UTF-8");
cr.setMaxUploadSize(26214400);
return cr;
}
选项 2 - 重命名方法
@Bean
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver cr = new CommonsMultipartResolver();
cr.setDefaultEncoding("UTF-8");
cr.setMaxUploadSize(26214400);
return cr;
}
对于大多数人来说,上述更改可能会解决问题。但是,由于进行上述更改后出现 ClassNotFoundException 错误,我还需要将 Apache Commons IO 添加到我的项目中。
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
有了这些更新,表单现在可以正确绑定了。我的问题已解决。