且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

09 Struts2 实现文件上传下载

更新时间:2022-08-22 10:20:30

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hxdeng/article/details/81710554

文件上传对Struts2来说是一件非常容易的事情。Struts2文件上传依赖如下jar包

commons-fileupload-x.x.x.jar
commons-io-x.x.x.jar

文件上传大致步骤:
1. 编写页面
2. 配置struts.xml 拦截器会自动接收上传的文件
3. 在Action中写代码,把上传的文件保存到服务器中
4. 响应客户端

==注意== 文件上传form表单的enctype=”multipart/form-data” 值需要修改

1. 单文件上传

==JSP页面==

<form action="" method="post" enctype="multipart/form-data"> 
    <input type="file" value="选择文件" name="file" /><br>
    <input type="submit" value="提交" />
</form>

==Action编写==
Action 类需要注意一下几点:
- 要声明与页面中表单==name属==性同名的属性,同名的属性的类型是==File类型==,该属性用来保存临时文件。
- 要声明==ContentType==属性,类型是==String类型==,该属性表示上传文件的类型。
- 要声明==FileName==属性,类型是==String类型==,该文件表示要上传的文件;
- 给所有属性提供get和set方法。

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

private File file;
private String fileContentType;
private String fileFileName;

public String fileUpload() throws IOException {
    System.out.println(fileContentType + "---" + fileFileName);

    ServletContext sc = ServletActionContext.getServletContext();
    // 获取要保存文件的位置
    String path = sc.getRealPath("/upload");
    // 创建一个与上传文件同名的文件
    File uploadFile = new File(path, fileFileName);
    // 将临时文件内容拷贝到目标文件夹下的那个同名的文件
    FileUtils.copyFile(file, uploadFile);
    // 删除临时文件
    file.delete();

    return "success";
}
//省略get/set方法

==注意==:Struts2默认上传文件总大小为2MB,超过文件总大小。需要修改大小如下:

<!-- 单位是字节 -->
<constant name="struts.multipart.maxSize" value="500000000" />

在Action下配置拦截器实现上传文件限制

<interceptor-ref name="fileUpload">
    <!--配置上传文件的大小,这里配置的是上传文件的单个大小-->
    <param name="maximumSize">20971520</param>   
    <!-- 配置上传文件允许的类型-->
    <param name="allowedTypes">image/pjpeg,image/jpeg,text/plain,application/msword</param>
    <!-- 配置上传文件的扩展名-->
    <param name="allowedExtensions">.txt,.doc</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>

==经验分享==
1. 在 Action 判断文件大小后再限制上传这是一种错误的做法。因为上传是在拦截器中完成的。它在运行Action之前,到了Action中在限制上传文件已经迟了(缓存文件已经保存到服务器)。
2. struts.multipart.maxSize 默认值是2M,如果上传大于2M的文件一定要修改其值
3. 由于不同浏览器对上传文件类型的定义区别,实现文件类型控制时需要考虑兼容性。例如:JPG文件需要在allowedTypes参数中定义image/pjpeg,image/jpeg两种类型
4. 配置拦截器时,不要忘记配置


2. 多文件上传

多文件上传的所有流程与单文件上传一致,但是需要注意的是:
- 在页面中,虽然是多文件上传,但是页面中表单的name属性的值必须保持一致;
- 在Action类中声明的相关属性,类型改成数组或者集合。
- 在业务方法中,相关处理流程改成单文件上传的循环。

==JSP页面==

<form action="filesUploadAction" method="post" enctype="multipart/form-data">
    <input type="file" value="选择文件" name="file" /><br /><br />
    <input type="file" value="选择文件" name="file" /><br /><br />
    <input type="file" value="选择文件" name="file" /><br /><br />
    <input type="file" value="选择文件" name="file" /><br /><br />

     <input type="submit" value="提交" />
</form>

==Action类==

private File[] file;
private String[] fileContentType;
private String[] fileFileName;

public String fileUpload() throws IOException {
    ServletContext sc = ServletActionContext.getServletContext();
    // 获取要保存文件的位置
    String path = sc.getRealPath("/upload");
    for (int i = 0; i < file.length; i++) {
        // 创建一个与上传文件同名的文件
        File uploadFile = new File(path, fileFileName[i]);
        // 将临时文件内容拷贝到目标文件夹下的那个同名的文件
        FileUtils.copyFile(file[i], uploadFile);
        // 删除临时文件
        file[i].delete();
    }
    return "success";
}

3. 文件下载

==JSP页面==

<a href="downloadFileAction?downloadFileName=3dd87b1aec.jpg">下载图片</a>

==struts.xml==

<!-- 文件下载 -->
<action name="downloadFileAction" class="com.javaee.struts2.action.DownloadFileAction" method="downloadFile">
    <result name="success" type="stream">
        <!-- 指定流方法 -->
        <param name="inputName">inputString</param>
        <!-- 下载保存的名字 -->
        <param name="contentDisposition">attachment;filename=${downloadFileName}</param>
        <!--指定下载文件的缓冲大小 -->
        <param name="bufferSize">4096</param>
        <!-- 设置下载文件的类型 -->
        <param name="contentType">${contentType}</param>
    </result>
</action>

==Action类==

//下载的文件名
private String downloadFileName;
//下载文件的保存路径
private String downPath;
//下载文件的类型
String contentType;

public String downloadFile() throws UnsupportedEncodingException {
    contentType = "application/x-msdownload";
    downPath = "down" + File.separator + downloadFileName;
    return SUCCESS;
}

public InputStream getInputString() throws FileNotFoundException {
//      return ServletActionContext.getServletContext().getResourceAsStream(downPath);
    String path = ServletActionContext.getServletContext().getRealPath("/down");
    return new FileInputStream(new File(path,downloadFileName));
}
//省略get/set方法