>

webwork文件上传,实现公文上传下载代码详解

- 编辑:正版管家婆马报彩图 -

webwork文件上传,实现公文上传下载代码详解

本文首要从三个地点给大家介绍webwork文件上传下载知识,包蕴以下多少个方面:

Webwork 学习之路(七)文件上传下载,webwork文件上传

      Web上传和下载应该是很广阔的三个须求,无论是Mini网址如故大并发访谈的贸易网址。WebWork 当然也提供了很和气的拦截器来落到实处对文本的上传,让大家得以小心与职业逻辑的筹划和促成,在贯彻上传和下载时顺手关怀了下框架上传下载的兑现,在本篇博文中计算记录如下。 

图片 1

  1. 包装 Request 请求
  2. 收获文件上传的深入分析类
  3. 品类实战陈设和选用

1. 包装 Request 请求

  • 每便客户端哀告 Action 时,都会调用 WebWork 调度类 ServletDispatcher.service()方法。

       具体经过请参照他事他说加以考察: 

    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,假使是就从来回到。
  •  不然再决断 request 的头音讯里面的 Content­Type 是还是不是多类型参数 (multipart/form­data)的伸手,假设是就把 request 包装成 WebWork 自己的 MultiPartRequestWrapper 类型,该品种承袭HttpServletRequestWrapper

    MultiPartRequest.isMultiPart() 方法落成如下:

 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 里头配备文件的一时存款和储蓄目录、还应该有最大上传大小,其实正是在那个时候起到效果的。
  • 创建 MultiPartRequestWrapper 对象的时候传出的参数是由 getSaveDir() 和 getMaxSize() 方 法 获 得 的 。
  • 在措施里会搜索配置内部的 webwork.multipart.saveDir、 webwork.multipart.maxSize 品质,找到则采用该属性内定的不时目录和上传的最大内容,没找到就应用条件的一时目录。

实际达成如下:

    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;
    }

Web上传和下载应该是很普及的三个须求,无论是Mini网站照旧大并发访谈的贸易网址。WebWork 当然也提供了很投机的拦截器来得以实现对文本的上传,让我们得以小心与专门的学问逻辑的宏图和促成,在完结上传和下载时顺手关心了下框架上传下载的兑现。

2. 收获文件上传的分析类     

   再来看一下 MultiPartRequestWrapper 的构造函数使怎么着包装 request 的:

    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
  •  不然读取 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参数名。借使直白使用 WebWorkFileUpload 拦截器,推荐使用pell,因为当您上传普通话文件名称的文书的时候,唯有pell 包会准确的获得中文文件名称,apache common会将文件名称改为xxx.tmp这样的文本名,而cos会乱码, 由此我们独一的选料唯有 pell。
  • cos 的功能相比强硬,WebWork 的包装却使它丧失了众多的效率,cos 须要设置 request 的character encoding。WebWork的包裹未有安装,所以就招致了cos的乱码难点,当然假如您独自 使用cos,则会幸免此类主题素材。

图片 2

3. 门类实战陈设和行使

  •  配置文件
action 配置:
 <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这里就十分少说了,有官方网站:
  • 透过对 Webwork 上传需要的包裹和平解决析类的取得,全数的前戏都早就盘算妥贴,上传拦截器里面具体落到实处如下:
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
  • 下一场推断在文书上传进度 MultiPartRequestWrapper 是不是包罗错误,将错误音信,重临给客商端,不在继续调用 Action
  • 假若地方的评定尺度都尚未开展,最早遍历 MultiPartRequestWrapper  中的上传文件的参数,并将中间的文书名、文件内容类型放入Action 参数 map 中,供前面的作业类进行操作。
  • 在 WebWork 的 fileupload 拦截器功能中,它提供的 File只 是一个临时文件,Action 施行之后就能被电动删除,你必需在 Action中温馨处理公事的仓库储存难题,只怕写到服务器的某些目录,大概封存到数据库中。若是您筹划写到服务器的某部目录上边包车型地铁话,你必须和睦面对着管理公事同名的题目,可是事实上cos包已经提供了 文件重名的活动重命名准绳。 

 

学习之路(七)文件上传下载,webwork文件上传 Web上传和下载应该是很广阔的叁个要求,无论是小型网址还是大并发访问的交易网址。...

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,假诺是就径直回到。
• 不然再决断 request 的头新闻里面包车型的士 Content­Type 是否多类型参数 (multipart/form­data)的伸手,若是是就把 request 包装成 WebWork 自个儿的 MultiPartRequestWrapper 类型,该品种继承HttpServletRequestWrapper 。

MultiPartRequest.isMultiPart() 方法达成如下:

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 里面配备文件的暂时存款和储蓄目录、还应该有最大上传大小,其实正是在这一年起到效果与利益的。
•成立 MultiPartRequestWrapper 对象的时候传出的参数是由 getSaveDir() 和 get马克斯Size() 方 法 获 得 的 。
•在艺术里会找寻配置内部的 webwork.multipart.saveDir、 webwork.multipart.maxSize 属性,找到则利用该属性钦定的近日目录和上传的最大内容,没找到就动用情状的暂时目录。

具体贯彻如下:

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. 赢得文件上传的剖析类

再来看一下 MultiPartRequestWrapper 的构造函数使怎样包装 request 的:

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。

• 否则读取 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. 品种实战铺排和动用

• 配置文件

action 配置:

<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 上传图片代码

•通过对 Webwork 上传哀告的包装和平化解析类的获得,全数的前戏都早已谋算妥贴,上传拦截器里面具体完结如下:

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。
•然后推断在文书上传进程 MultiPartRequestWrapper 是不是含有错误,将错误消息,重回给客商端,不在继续调用 Action。
•要是下面的推断规范都未曾进展,初叶遍历 MultiPartRequestWrapper 中的上传文件的参数,并将里面的文本名、文件内容类型归入Action 参数 map 中,供后边的事体类进行操作。
•在 WebWork 的 fileupload 拦截器效用中,它提供的 File只 是三个有的时候文件,Action 试行之后就能被自动删除,你必得在 Action中友好处理公事的存放难点,可能写到服务器的有个别目录,也许封存到数据库中。假设您计划写到服务器的某部目录下面包车型客车话,你必得自身面前碰着着拍卖文件同名的主题素材,可是实际cos包已经提供了 文件重名的电动重命名法则。

透过以上代码给大家介绍了Webwork 达成公文上传下载的连带文化,希望对大家有所扶助。

你或然感兴趣的篇章:

  • 详解Webwork中Action 调用的措施

本文由关于计算机发布,转载请注明来源:webwork文件上传,实现公文上传下载代码详解