Java自学笔记之struts2 文件上传

来源:互联网 发布:郭德纲 陈宝国 知乎 编辑:程序博客网 时间:2024/06/11 04:53

1、在Javaweb中文件上传,对前台表单的要求是,必须是post方式提交,enctype必须是multipart/form-data,也就是类似于这样的

<form action="${pageContext.request.contextPath}/servlet/UploadServlet2"  method="post"  enctype="multipart/form-data" >     <input  type="file"  name="photo" /><br />     <input type="submit"  value="提交" /></form>

对Servlet怎么写呢?三步,获取DisFileItemFactory,获取ServletFileUpload,解析request获取List<FileItem>

boolean isMultipart = ServletFileUpload.isMultipartContent(request);        if (!isMultipart) {            throw new RuntimeException("error!");        }        DiskFileItemFactory factory = new DiskFileItemFactory();        ServletFileUpload sfu = new ServletFileUpload(factory);        try {            List<FileItem> fileItems = sfu.parseRequest(request);            for (FileItem fileItem : fileItems) {                if (fileItem.isFormField()) {                    ...                }else {                    ...                }            }        } catch (FileUploadException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }

当然,需要的jar包必须导入,commons-fileupload.jar、commons-io.jar包,web.xml必须把Servlet进行配置。

2、上面是传统Javaweb对文件上传的处理方法,现在要用struts进行文件上传,struts文件上传分为单文件上传和多文件上传,这里先讨论单文件上传
2.1、表单的要求也是和javaweb一样,比如:

<form action="${pageContext.request.contextPath}/upload.action" method="post" enctype="multipart/form-data">         <input type="text" name="title">         <input type="file" name="myFile">         <input type="submit" value="上传">         </form>  

2.2对action的要求:
在Action类中声明相关属性:

  • 要声明与页面中表单name属性同名的属性,同名的属性的类型是File类型,该属性用来保存临时文件;
  • 要声明[同名的属性]ContentType属性,类型是String类型,该属性表示上传文件的类型;
  • 要声明[同名的属性]FileName属性,类型是String类型,该文件表示要上传的文件;
  • 给所有属性提供get和set方法。

在Action类中提供处理上传的方法:

  • 获取要保存文件的位置;
  • 在目标文件夹内,创建一个与上传文件同名的文件;
  • 通过FileUtils工具类提供copyFile()方法,将临时文件内容拷贝到目标文件夹下的那个同名的文件;
  • 调用保存临时文件的属性的delete()方法删除临时文件(也就是File类型属性的delete方法)

2.3、配置struts.xml文件,设置上传文件总大小,Struts2默认上传文件总大小为2MB,超过文件总大小,跳转input视图,通过<s:actionError /> 回显错误信息,在struts.xml 设置上传总大小(单位是字节):

<constant name="struts.multipart.maxSize" value="20480000"></constant>

2.4、在fileUpload拦截器中有三个属性:

  • protected Long maximumSize:可以设置每一个上传文件的大小
  • protected Set allowedTypesSet:设置允许上传文件的类型
  • protected Set allowedExtensionsSet:设置允许的上传文件的后缀名
    2.5、单文件上传的例子
    表单:
<form action="${pageContext.request.contextPath}/UploadAction"        method="post" enctype="multipart/form-data">        <input type="text" name="name" /><br />         <input type="file" name="photo" /><br />        <input type="submit" value="提交" />    </form>

action类:

package com.action;import java.io.File;import java.io.IOException;import org.apache.commons.io.FileUtils;import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.ActionSupport;public class UploadAction extends ActionSupport{    private String name;    // 这会是上传文件的临时文件,上传成功后最好删除    private File photo;    // 这是上传文件的类型    private String photoContentType;    // 这是上传文件的真实文件路径    private String photoFileName;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public File getPhoto() {        return photo;    }    public void setPhoto(File photo) {        this.photo = photo;    }    public String getPhotoContentType() {        return photoContentType;    }    public void setPhotoContentType(String photoContentType) {        this.photoContentType = photoContentType;    }    public String getPhotoFileName() {        return photoFileName;    }    public void setPhotoFileName(String photoFileName) {        this.photoFileName = photoFileName;    }    public String execute() throws IOException{        String path = ServletActionContext.getServletContext().getRealPath("/upload");        File file = new File(path,photoFileName);        FileUtils.copyFile(photo, file);        photo.delete();        return "success";    }}

struts.xml

<package name="uploadAction" namespace="/" extends="struts-default">        <action name="UploadAction" class="com.action.UploadAction" method="execute">            <result name="success">/success.jsp</result>        </action>    </package>

如果异常的话,可以在tomcat目录/webapps/自己目录的对应地方查看是否上传成功了,在myeclipce是看不到的,因为上传到的目录在tomcat/webapps下;
2.6、如果限制上传txt和doc的文件,上传大小收到限制,配置文件应该这么写:

<struts>    <!-- 设置上传文件的总大小限制  2048000000字节=2048G=2T -->    <constant name="struts.multipart.maxSize" value="2048000000"></constant>    <package name="uploadAction" namespace="/" extends="struts-default">        <action name="UploadAction" class="com.action.UploadAction"            method="execute">            <result name="success">/success.jsp</result>            <interceptor-ref name="defaultStack">                <!-- 配置文件上传拦截器的参数  与定义参数的顺序无关  允许的类型(allowedTypes)和允许的扩展名(allowedExtensions)必须保持一致 -->                <!-- * 配置上传文件的大小  struts.xml文件中配置的是上传文件的总大小  这里配置的是上传文件的单个大小 -->                <param name="fileUpload.maximumSize">20971520</param>                <!-- 配置上传文件允许的类型,如果配置多个值的话,用","隔开 -->                <param name="fileUpload.allowedTypes">text/plain,application/msword</param>                <!-- 配置上传文件的扩展名,如果配置多个值的话,用","隔开 -->                <param name="fileUpload.allowedExtensions">.txt,.doc</param>            </interceptor-ref>        </action>    </package></struts>

3、多文件上传
多文件上传的所有流程与单文件上传一致,但是需要注意的是:

  • 在页面中,虽然是多文件上传,但是页面中表单的name属性的值必须保持一致;
  • 在Action类中声明的相关属性,类型改成数组或者集合;
  • 在业务方法中,相关处理流程改成单文件上传的循环。
    单文件上传示例:
    JSP:
<body> <form action="${pageContext.servletContext.contextPath}/uploadAction.action" enctype="multipart/form-data" method="post">    上传文件:<input type="file" name="upload"><br>    上传文件:<input type="file" name="upload"><br>    上传文件:<input type="file" name="upload"><br>    上传文件:<input type="file" name="upload"><br>    <input type="submit" value="上传"> </form></body>

action类:

public class UploadAction extends ActionSupport {    private File[] upload;    private String[] uploadContentType;    private String[] uploadFileName;    public File[] getUpload() {        return upload;    }    public void setUpload(File[] upload) {        this.upload = upload;    }    public String[] getUploadContentType() {        return uploadContentType;    }    public void setUploadContentType(String[] uploadContentType) {        this.uploadContentType = uploadContentType;    }    public String[] getUploadFileName() {        return uploadFileName;    }    public void setUploadFileName(String[] uploadFileName) {        this.uploadFileName = uploadFileName;    }    @Override    public String execute() throws Exception {        ServletContext sc = ServletActionContext.getServletContext();        //获取要保存文件的位置        String path = sc.getRealPath("/upload");        //创建一个与上传文件同名的文件        for (int i = 0; i < upload.length; i++) {            File file = new File(path, uploadFileName[i]);            //将临时文件内容拷贝到目标文件夹下的那个同名的文件            FileUtils.copyFile(upload[i], file);            //删除临时文件            upload[i].delete();        }        return SUCCESS;    }}

struts.xml:

<struts>    <constant name="struts.devMode" value="true" />    <constant name="struts.multipart.maxSize" value="200000000"/>     <package name="default" namespace="/" extends="struts-default">        <action name="uploadAction" class="com.sunny.action.UploadAction">            <result>/success.jsp</result>            <result name="input">/error.jsp</result>            <interceptor-ref name="defaultStack">                <param name="fileUpload.maximumSize">20971520</param>                <param name="fileUpload.allowedTypes">text/plain,application/msword</param>                <param name="fileUpload.allowedExtensions">.txt,.doc</param>            </interceptor-ref>        </action>    </package></struts>