点击上传按钮后,webwork的程序流如下:step 1)进入servletdispatcher.service执行完第四步,然后推出servletdispatcher.wraprequest,进入serviceaction方法,开始action及其拦截器的栈调用
public void service(httpservletrequest request, httpservletresponse response) throws servletexception {
........
request = wraprequest(request);
.........
}
step2)进入servletdispatcher.wraprequest
protected httpservletrequest wraprequest(httpservletrequest request) throws ioexception {
........................
if (multipartrequest.ismultipart(request)) {
request = new multipartrequestwrapper(request, getsavedir(), getmaxsize());
}
return request;
}
step3)进入multipartrequestwrapper的构造方法
public multipartrequestwrapper(httpservletrequest request, string savedir, int maxsize) throws ioexception {
.....................
//step3.1)获取webwork.preperties配置的parser
string parser = "";
parser = configuration.getstring("webwork.multipart.parser");
// if it's not set, use pell
if (parser.equals("")) {
log.warn("property webwork.multipart.parser not set." +
" using com.opensymphony.webwork.dispatcher.multipart.pellmultipartrequest");
parser = "com.opensymphony.webwork.dispatcher.multipart.pellmultipartrequest";
}
// legacy support for old style property values
else if (parser.equals("pell")) {
parser = "com.opensymphony.webwork.dispatcher.multipart.pellmultipartrequest";
} else if (parser.equals("cos")) {
parser = "com.opensymphony.webwork.dispatcher.multipart.cosmultipartrequest";
} else if (parser.equals("jakarta")) {
parser = "com.opensymphony.webwork.dispatcher.multipart.jakartamultipartrequest";
}
//step3.2)获取后通过反射实例化parser
try {
class baseclazz = com.opensymphony.webwork.dispatcher.multipart.multipartrequest.class;
class clazz = class.forname(parser);
// make sure it extends multipartrequest
if (!baseclazz.isassignablefrom(clazz)) {
adderror("class '" + parser + "' does not extend multipartrequest");
return;
}
// get the constructor
constructor ctor = clazz.getdeclaredconstructor(new class[]{
class.forname("javax.servlet.http.httpservletrequest"),
java.lang.string.class, int.class
});
// build the parameter list
object[] parms = new object[]{
request, savedir, new integer(maxsize)
};
// instantiate it
multi = (multipartrequest) ctor.newinstance(parms);
.................................................
}
//step4 进入jakartamultipartrequest的构造方法(我在webwork配置的parser是jakarta所以进入了这个方法,如果你配置不同的parser回进入不同的parser
public jakartamultipartrequest(httpservletrequest servletrequest, string savedir, int maxsize)
throws ioexception {
//设置保存参数
diskfileupload upload = new diskfileupload();
// we must store all uploads on disk because the ww multipart api is missing streaming
// capabilities
upload.setsizethreshold(0);
upload.setsizemax(maxsize);
if (savedir != null) {
upload.setrepositorypath(savedir);
}
// parse the request
try {
//此方法生成文件,将请求中的每个参数都生成一个临时文件比如upload_00000017.tmp, upload_00000018.tmp等,就算是form提交的参数也如此
list items = upload.parserequest(servletrequest);
......................
}
在此过程中会删除非上传文件的临时文件,至于哪一步删除,我还没看出来,有时候很早有时候很晚,有时候甚至没有删除,我怀疑有个dameon在做这个事。
进入action和调用栈后,拦截器或action可通过如下代码访问上传的临时文件
multipartrequestwrapper wrapper = (multipartrequestwrapper) req;
file doc = wrapper.getfiles("doc")[0];
从上面的分析可以看出:
1)如果你使用webwork来上传文件(在进入action栈之前不修改源码或者做一些扩展、覆盖之类的动作),在进入action栈的时候文件已经上 传,而且其文件名很难跟踪(upload_00000017.tmp,到底是00000017,0000018,或者0000022等等),毕竟有很多人 上传文件,所以临时文件名很难确定,所以如果你想知道上传的进度很难。
2)利用webwork上传文件是两次拷贝过程,webwork首先从request的输入流中将文件流输出到一个临时文件,然后你再将此临时文件拷贝到你需要指定的路径。这是好是坏?
闽公网安备 35060202000074号