Webwork如何处理request
摘要
在《Webwork基本原理》中,
FilterDispatcher.doFilter
-
将Request.parameter->map中
ActionMapping mapping = mapper.getMapping(request);
webwork将request包装成了mapping,交给xwork处理。
而request数据有三种(实际上是两种)类型,
-
application/x-www-form-urlencoded:用来传输小数据量数据
-
multipart/form-data:用来处理文件上传
-
text/plain:以纯文本形式传送信息
主要用到application/x-www-form-urlencoded和multipart/form-data两种
而两种类型的form,处理方式也不一样。
-
application/x-www-form-urlencoded是基于键值对的方式
-
multipart/form-data更类似于流的方式。
Webwork2把这两种方式统一了起来。
源代码
-
FilterDispatcher.doFilter
request = du.wrapRequest(request, servletContext);
调用了DispatcherUtils. wrapRequest,返回一个HttpServletRequest对象,为了看得更清楚我将里面的方法简化了一下
public HttpServletRequest wrapRequest(HttpServletRequest request, ServletContext servletContext) throws IOException {
……
if (MultiPartRequest.isMultiPart(request)) {//如果是multipart/form-data
request = new MultiPartRequestWrapper(request, getSaveDir(servletContext), getMaxSize());
} else {//否则是application/x-www-form-urlencoded
request = new WebWorkRequestWrapper(request);
}
return request;
}
给出类图会看得更清楚
这个类图很明白地说明了wrap结构:
-
MultiPartRequestWrapper处理multi类型的request,
-
WebWorkRequestWrapper处理普通类型。
WebWorkRequestWrapper只是一个普通的request包装,我们重点看看MultiPartRequestWrapper
-
MultiPartRequestWrapper
//读取WebWorkConstants.WEBWORK_MULTIPART_PARSER,看看用的什么上传组件
String parser = Configuration.getString(WebWorkConstants.WEBWORK_MULTIPART_PARSER);
//默认, use Jakarta
if (parser.equals("")) {
parser = "com.opensymphony.webwork.dispatcher.multipart.JakartaMultiPartRequest";
}
// 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";
}
//调用一个classloader
Class clazz = ClassLoaderUtils.loadClass(parser, MultiPartRequestWrapper.class);
下面以默认的
com.opensymphony.webwork.dispatcher.multipart.JakartaMultiPartRequest为例
JakartaMultiPartRequest(HttpServletRequest servletRequest, String saveDir, int maxSize)
//反射得到该类的实例
multi = (MultiPartRequest) ctor.newInstance(parms);
在这个类中,调用了org.apache.commons.fileupload的方法,解析request,这个构造函数中有一个params.put(item.getFieldName(), values);
这个类还有一个getParameter方法
public String getParameter(String name) {
List v = (List) params.get(name);
if (v != null && v.size() > 0) {
return (String) v.get(0);
}
return null;
}
最后
JakartaMultiPartRequest解析完request后,MultiPartRequestWrapper对结果做了一个包装,包装成了一个request对象,实现了getParameterMap()等方法。
然后就可以request.getParameterMap(),用这一个方法完成参数的获取了。