一、项目基本环境:struts2等
二、基本需求&问题:需要自己写程序调用common-fileupload来处理上传的文件,但在代码调用upload.parseRequest(request)来处理时,返回了空的items
commons-io在struts框架中无法获取upload.parseRequest(request)上传的文件的主要原因是因为struts将request进行了封装,在文件上传时struts会将HttpServletRequest请求被转成了MultiPartRequestWrapper,所以如需使用request,则需要将struts封装好的的MultiPartRequestWrapper转换成HttpServletRequest
三。处理方法
(1)1、按照网上找到对该问题的相关处理方法:
- <filter-mapping>
- <filter-name>struts2</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
修改为
- <filter-mapping>
- <filter-name>struts2</filter-name>
- <url-pattern>*.action</url-pattern>
- </filter-mapping>
但是这样的话,本身项目里面拦截的东西很多,那样我就要一一使用filter加进去,这样很麻烦,不采用。
这个方法主要是使这个servelt不被拦截。
(2) 操作一:创建java类,继承JakartaMultiPartRequest,代码如下:
public class RequestParseWrapper extends JakartaMultiPartRequest {
操作二: 在struts配置文件里添加上,代码如下:public void parse(HttpServletRequest servletRequest, String saveDir)throws IOException{
}
}
<!-- 出来文件上传时servletFileUpload.parseRequest(request)取不到值的问题 -->
<bean type= "org.apache.struts2.dispatcher.multipart.MultiPartRequest"
name= "myRequestParser" class= "com.turui.util.RequestParseWrapper"
scope= "default" optional= "true " />
<constant name= "struts.multipart.handler" value= "myRequestParser" />
这里的class是指操作一创建的java类
这个方法在网上看,有很多人用,我也使用了,解决了问题,但是同样出现了其他问题。因为我只有一个页面是使用了ajax提交type=file类型的表单,其他页面还是直接使用form表单的submit,定义了类型multipart/form-data
按照上面的方法处理后,这些页面就不能正常提交了,获取的数去是Null,,原因我认为主要是上面加了type类型,可是如果不加的话提交也是失败的,等待再分析。使用ajax提交含file的表单
$(
'#form1'
).submit(
function
() {
var
formdata =
new
FormData();
var
fileObj = document.getElementById(
"fileToUpload2"
).files;
for
(
var
i = 0; i < fileObj.length; i++)
formdata.append(
"file"
+ i, fileObj[i]);
$.ajax({
type:
'POST'
,
url:
'/Home/Upload2'
,
data: formdata,
/**
*必须false才会自动加上正确的Content-Type
*/
contentType:
false
,
/**
* 必须false才会避开jQuery对 formdata 的默认处理
* XMLHttpRequest会对 formdata 进行正确的处理
*/
processData:
false
}).then(
function
() {
alert(
'done'
);
},
function
() {
//failCal
});
return
false
;
});
contentType必需设置为false,这样会被默认处理.所以这种方法还是没有解决问题。(3)获取为空主要是因为struts拦截的默认处理,那么如果我在struts拦截之前先做处理呢?于是,我自己实现一个servlet.Filter,并且把它的filter次序放到struts2的filter次序之前。主要源码如下:
这里先用StrutsRequestWrapper来给他wrapper一次,这样在经过struts2的filter的时候就不会有问题了。为啥呢?可以自己看看这个类
- public void doFilter(ServletRequest request, ServletResponse response,
- FilterChain chain) throws IOException, ServletException {
- chain.doFilter(new StrutsRequestWrapper((HttpServletRequest) request), response);
- }
org.apache.struts2.dispatcher.Dispatcher里面的wrapRequest方法,有这么个判断:
- // don't wrap more than once
- if (request instanceof StrutsRequestWrapper) {
- return request;
- }