
1. 包装 Request 请求
•每次客户端请求 Action 时,都会调用 WebWork 调度类 ServletDispatcher.service()方法。
具体过程请参照:详解Webwork中Action 调用的方法
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException {try {if (encoding != null) {try {request.setCharacterEncoding(encoding);} catch (Exception localException) {}}if (locale != null) {response.setLocale(locale);}if (this.paramsWorkaroundEnabled) {request.getParameter("foo");}request = wrapRequest(request); //封装 request请求serviceAction(request, response, getNameSpace(request), getActionName(request), getRequestMap(request), getParameterMap(request), getSessionMap(request), getApplicationMap());} catch (IOException e) {String message = "Could not wrap servlet request with MultipartRequestWrapper!";log.error(message, e);sendError(request, response, 500, new ServletException(message, e));}} 先来看看 wrapRequest 方法做了什么:protected HttpServletRequest wrapRequest(HttpServletRequest request) throws IOException {if ((request instanceof MultiPartRequestWrapper)) {return request;}if (MultiPartRequest.isMultiPart(request)) {request = new MultiPartRequestWrapper(request, getSaveDir(), getMaxSize());}return request;}• 首先判断了传进来的 request 是不是已经被封装好的 MultiPartRequestWrapper,如果是就直接返回。public static boolean isMultiPart(HttpServletRequest request){String content_type = request.getHeader("Content-Type");return content_type != null && content_type.startsWith("multipart/form-data");}•在 webwork.properties 里面配置文件的临时存储目录、还有最大上传大小,其实就是在这个时候起到作用的。protected String getSaveDir() {String saveDir = Configuration.getString("webwork.multipart.saveDir").trim();if (saveDir.equals("")) {File tempdir = (File) getServletConfig().getServletContext().getAttribute("javax.servlet.context.tempdir");log.info("Unable to find "webwork.multipart.saveDir" property setting. Defaulting to javax.servlet.context.tempdir");if (tempdir != null) {saveDir = tempdir.toString();}} else {File multipartSaveDir = new File(saveDir);if (!multipartSaveDir.exists()) {multipartSaveDir.mkdir();}}if (log.isDebugEnabled()) {log.debug("saveDir=" + saveDir);}return saveDir;}2. 获取文件上传的解析类 public MultiPartRequestWrapper(HttpServletRequest request, String saveDir, int maxSize) throws IOException {super(request);if ((request instanceof MultiPartRequest)) {this.multi = ((MultiPartRequest) request);} else {String parser = "";parser = Configuration.getString("webwork.multipart.parser");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";} 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";}try {Class baseClazz = MultiPartRequest.class;Class clazz = Class.forName(parser);if (!baseClazz.isAssignableFrom(clazz)) {addError("Class "" + parser + "" does not extend MultiPartRequest");return;}Constructor ctor = clazz.getDeclaredConstructor(new Class[] { Class.forName("javax.servlet.http.HttpServletRequest"), String.class, Integer.TYPE });Object[] parms = { request, saveDir, new Integer(maxSize) };this.multi = ((MultiPartRequest) ctor.newInstance(parms));} catch (ClassNotFoundException e) {addError("Class: " + parser + " not found.");} catch (NoSuchMethodException e) {addError("Constructor error for " + parser + ": " + e);} catch (InstantiationException e) {addError("Error instantiating " + parser + ": " + e);} catch (IllegalAccessException e) {addError("Access errror for " + parser + ": " + e);} catch (InvocationTargetException e) {addError(e.getTargetException().toString());}}}• 首先它判断了传入的 request 是不是 MultiPartRequest 抽象类的子类,如果是就直接把自身的 MultiPartRequest 类型的变量引用 request。<action name="uploadAttach" class=".....attach.action.uploadAttach" caption="上传附件"><result name="success" type="dispatcher"><param name="location">/result.jsp</param></result><result name="error" type="dispatcher"><param name="location">/result.jsp</param></result> <interceptor-ref name="defaultStack" /> <interceptor-ref name="fileUploadStack" /> //webwok 上传所需要的拦截栈</action>//拦截栈的定义<interceptor-stack name="fileUploadStack"><interceptor-ref name="fileUpload"/> <interceptor-ref name="params"/></interceptor-stack>//拦截栈对应的拦截器<interceptor name="fileUpload" class="com.opensymphony.webwork.interceptor.FileUploadInterceptor"/><interceptor name="params" class="com.opensymphony.xwork.interceptor.ParametersInterceptor"/>•前端使用比较稳定、功能比较强大的 Ajaxupload这里就不多说了,有官方网址:jQuery AjaxUpload 上传图片代码
public String intercept(ActionInvocation invocation) throws Exception {if (!(ServletActionContext.getRequest() instanceof MultiPartRequestWrapper)) {if (log.isDebugEnabled()) {log.debug("bypass " + invocation.getProxy().getNamespace() + "/" + invocation.getProxy().getActionName());}return invocation.invoke();}Action action = invocation.getAction();ValidationAware validation = null;if ((action instanceof ValidationAware)) {validation = (ValidationAware) action;}MultiPartRequestWrapper multiWrapper = (MultiPartRequestWrapper) ServletActionContext.getRequest();if (multiWrapper.hasErrors()) {Collection errors = multiWrapper.getErrors();Iterator i = errors.iterator();while (i.hasNext()) {String error = (String) i.next();if (validation != null) {validation.addActionError(error);}log.error(error);}}Enumeration e = multiWrapper.getFileParameterNames();while ((e != null) && (e.hasMoreElements())) {String inputName = (String) e.nextElement();String[] contentType = multiWrapper.getContentTypes(inputName);String[] fileName = multiWrapper.getFileNames(inputName);File[] file = multiWrapper.getFiles(inputName);if (file != null) {for (int i = 0; i < file.length; i++) {log.info("file " + inputName + " " + contentType[i] + " " + fileName[i] + " " + file[i]);}}if (file == null) {if (validation != null) {validation.addFieldError(inputName, "Could not upload file(s). Perhaps it is too large?");}log.error("Error uploading: " + fileName);} else {invocation.getInvocationContext().getParameters().put(inputName, file);invocation.getInvocationContext().getParameters().put(inputName + "ContentType", contentType);invocation.getInvocationContext().getParameters().put(inputName + "FileName", fileName);}}String result = invocation.invoke();for (Enumeration e1 = multiWrapper.getFileParameterNames(); e1 != null && e1.hasMoreElements();) {String inputValue = (String) e1.nextElement();File file[] = multiWrapper.getFiles(inputValue);for (int i = 0; i < file.length; i++) {File f = file[i];log.info("removing file " + inputValue + " " + f);if (f != null && f.isFile())f.delete();}}return result;}•首先判断当前请求是否为 包含多媒体请求,如果是则记录日志,并执行 Action。