实现文件上传下载代码详解_javascript技巧_脚本之

2020-01-04 作者:亚洲城动态   |   浏览(83)

本文主要从三个方面给大家介绍webwork文件上传下载知识,包括以下三个方面:

  1. 包装 Request 请求2. 获取文件上传的解析类 3. 项目实战配置和使用

Web上传和下载应该是很普遍的一个需求,无论是小型网站还是大并发访问的交易网站。WebWork 当然也提供了很友好的拦截器来实现对文件的上传,让我们可以专注与业务逻辑的设计和实现,在实现上传和下载时顺便关注了下框架上传下载的实现。

1. 包装 Request 请求

•每次客户端请求 Action 时,都会调用 WebWork 调度类 ServletDispatcher.service()方法。

具体过程请参照:详解Webwork中Action 调用的方法

public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException {try {if  {try {request.setCharacterEncoding;} catch (Exception localException) {}}if  {response.setLocale;}if (this.paramsWorkaroundEnabled) {request.getParameter;}request = wrapRequest; //封装 request请求serviceAction(request, response, getNameSpace, getActionName, getRequestMap, getParameterMap, getSessionMap, getApplicationMap;} catch  {String message = "Could not wrap servlet request with MultipartRequestWrapper!";log.error;sendError(request, response, 500, new ServletException;}} 

先来看看 wrapRequest 方法做了什么:

protected HttpServletRequest wrapRequest(HttpServletRequest request) throws IOException {if ((request instanceof MultiPartRequestWrapper)) {return request;}if (MultiPartRequest.isMultiPart {request = new MultiPartRequestWrapper, getMaxSize;}return request;}

• 首先判断了传进来的 request 是不是已经被封装好的 MultiPartRequestWrapper,如果是就直接返回。• 否则再判断 request 的头信息里面的 Content­Type 是不是多类型参数 (multipart/form­data)的请求,如果是就把 request 包装成 WebWork 自己的 MultiPartRequestWrapper 类型,该类型继承HttpServletRequestWrapper 。

MultiPartRequest.isMultiPart() 方法实现如下:

public static boolean isMultiPart(HttpServletRequest request){String content_type = request.getHeader;return content_type != null && content_type.startsWith("multipart/form-data");}

•在 webwork.properties 里面配置文件的临时存储目录、还有最大上传大小,其实就是在这个时候起到作用的。•创建 MultiPartRequestWrapper 对象的时候传入的参数是由 getSaveDir 方 法 获 得 的 。•在方法里会查找配置里面的 webwork.multipart.saveDir、 webwork.multipart.maxSize 属性,找到则使用该属性指定的临时目录和上传的最大内容,没找到就使用环境的临时目录。

protected String getSaveDir() {String saveDir = Configuration.getString("webwork.multipart.saveDir").trim();if  {File tempdir =  getServletConfig.getAttribute("javax.servlet.context.tempdir");log.info("Unable to find 'webwork.multipart.saveDir' property setting. Defaulting to javax.servlet.context.tempdir");if  {saveDir = tempdir.toString();}} else {File multipartSaveDir = new File;if (!multipartSaveDir.exists {multipartSaveDir.mkdir();}}if  {log.debug;}return saveDir;}

2. 获取文件上传的解析类

亚洲城官网,再来看一下 MultiPartRequestWrapper 的构造函数使如何包装 request 的:

public MultiPartRequestWrapper(HttpServletRequest request, String saveDir, int maxSize) throws IOException {super;if ((request instanceof MultiPartRequest)) {this.multi =  request);} else {String parser = "";parser = Configuration.getString("webwork.multipart.parser");if  {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 = "com.opensymphony.webwork.dispatcher.multipart.PellMultiPartRequest";} else if  {parser = "com.opensymphony.webwork.dispatcher.multipart.CosMultiPartRequest";} else if (parser.equals {parser = "com.opensymphony.webwork.dispatcher.multipart.JakartaMultiPartRequest";}try {Class baseClazz = MultiPartRequest.class;Class clazz = Class.forName;if (!baseClazz.isAssignableFrom {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 };this.multi =  ctor.newInstance;} 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;}}}

• 首先它判断了传入的 request 是不是 MultiPartRequest 抽象类的子类,如果是就直接把自身的 MultiPartRequest 类型的变量引用 request。

• 否则读取 WebWork 配置 的webwork.multipart.parser 属性,该属性决定 Webwork 内部用什么实现文件上传。 如果没有指定,则默认使用 PellMultiPartRequest 的实现。

•找到配置的类后,WebWork 通过 Java 反射创建该类的实例。所有支持的类都是从 MultiPartRequest 继承而来,创建该实例后向上转型,并赋予 MultiPartRequestWrapper 的成员multi。

• WebWork 的文件上传封装了几种通用的 FileUpload lib,并不是自己实现的。

•它包括了pell,cos,apache common 三种实现,WebWork 对这三个包进行封装,提供了一 个通用的访问接口 MultiPartRequest,细节实现分别是 PellMultiPartRequest、 CosMultiPartRequest 、JakartaMultiPartRequest 。

• jakarta 支持多个文件使用同一个HTTP参数名。如果直接使用 WebWork 的 FileUpload 拦截器,推荐使用pell,因为当你上传中文文件名称的文件的时候,只有pell 包会正确的获得中文文件名称,apache common会将文件名称改为xxx.tmp这样的文件名,而cos会乱码, 因此我们唯一的选择只有 pell。

•cos 的功能比较强大,WebWork 的封装却使它丧失了很多的功能,cos 需要设置 request 的character encoding。WebWork的封装没有设置,所以就导致了cos的乱码问题,当然如果你单独 使用cos,则会避免此类问题。

3. 项目实战配置和使用

• 配置文件

/result.jsp/result.jsp   //webwok 上传所需要的拦截栈//拦截栈的定义 //拦截栈对应的拦截器 

•前端使用比较稳定、功能比较强大的 Ajaxupload这里就不多说了,有官方网址:jQuery AjaxUpload 上传图片代码

•通过对 Webwork 上传请求的封装和解析类的获取,所有的前戏都已经准备妥当,上传拦截器里面具体实现如下:

public String intercept(ActionInvocation invocation) throws Exception {if (!(ServletActionContext.getRequest() instanceof MultiPartRequestWrapper)) {if  {log.debug("bypass "   invocation.getProxy   "/"   invocation.getProxy;}return invocation.invoke();}Action action = invocation.getAction();ValidationAware validation = null;if ((action instanceof ValidationAware)) {validation =  action;}MultiPartRequestWrapper multiWrapper = (MultiPartRequestWrapper) ServletActionContext.getRequest();if (multiWrapper.hasErrors {Collection errors = multiWrapper.getErrors();Iterator i = errors.iterator {String error = ;if  {validation.addActionError;}log.error;}}Enumeration e = multiWrapper.getFileParameterNames &&  {String inputName =  e.nextElement();String[] contentType = multiWrapper.getContentTypes;String[] fileName = multiWrapper.getFileNames;File[] file = multiWrapper.getFiles;if  {for (int i = 0; i < file.length; i  ) {log.info("file "   inputName   " "   contentType[i]   " "   fileName[i]   " "   file[i]);}}if  {if  {validation.addFieldError(inputName, "Could not upload file. Perhaps it is too large?");}log.error("Error uploading: "   fileName);} else {invocation.getInvocationContext.put;invocation.getInvocationContext.put(inputName   "ContentType", contentType);invocation.getInvocationContext.put(inputName   "FileName", fileName);}}String result = invocation.invoke();for (Enumeration e1 = multiWrapper.getFileParameterNames(); e1 != null && e1.hasMoreElements {String inputValue =  e1.nextElement();File file[] = multiWrapper.getFiles;for (int i = 0; i < file.length; i  ) {File f = file[i];log.info("removing file "   inputValue   " "   f);if (f != null && f.isFile;}}return result;}

•首先判断当前请求是否为 包含多媒体请求,如果是则记录日志,并执行 Action。•然后判断在文件上传过程 MultiPartRequestWrapper 是否含有错误,将错误信息,返回给客户端,不在继续调用 Action。•如果上面的判断条件都没有进行,开始遍历 MultiPartRequestWrapper 中的上传文件的参数,并将其中的文件名、文件内容类型放入Action 参数 map 中,供后面的业务类进行操作。•在 WebWork 的 fileupload 拦截器功能中,它提供的 File只 是一个临时文件,Action 执行之后就会被自动删除,你必须在 Action中自己处理文件的存储问题,或者写到服务器的某个目录,或者保存到数据库中。如果你准备写到服务器的某个目录下面的话,你必须自己面临着处理文件同名的问题,但是实际上cos包已经提供了 文件重名的自动重命名规则。

通过以上代码给大家介绍了Webwork 实现文件上传下载的相关知识,希望对大家有所帮助。

本文由yzc216亚洲城发布于亚洲城动态,转载请注明出处:实现文件上传下载代码详解_javascript技巧_脚本之

关键词: 亚洲城官网 yzc216亚洲城