Spring MVC学习总结(八):文件上传与下载

一、传统方式的文件上传

(1)引入jar包

    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.1</version>
    </dependency>

(2)在index.jsp编写文件上传的表单

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
   
</head>
<body>
<h3>传统方式文件上传</h3>
<form method="post" action="${pageContext.request.contextPath }/user/uploadFile01" enctype="multipart/form-data">
    选择文件:<input type="file" name="upload"><br>
    <input type="submit" value="上传">
</form>
</body>
</html>

注意:

a.标签 <input type="file"/> 会在浏览器中显示一个输入框和一个按钮,输入框可供用户填写本地文件的文件名和路径名,按钮可以让浏览器打开一个文件选择框供用户选择文件。

b.表单的 enctype 属性指定的是表单数据的编码方式,该属性有以下 3 个值。

  • application/x-www-form-urlencoded:这是默认的编码方式,它只处理表单域里的 value 属性值。
  • multipart/form-data:该编码方式以二进制流的方式来处理表单数据,并将文件域指定文件的内容封装到请求参数里。
  • text/plain:该编码方式只有当表单的 action 属性为“mailto:”URL 的形式时才使用,主要适用于直接通过表单发送邮件的方式。

 (3)在UserConrtoller添加方法。

    @RequestMapping("/uploadFile01")
    public String uploadFile01(HttpServletRequest request) throws Exception {
        System.out.println("传统方式文件上传");
        //文件上传的位置
        String path = request.getSession().getServletContext().getRealPath("/uploads");
        File file = new File(path);
        //文件夹不存在则创建文件夹
        if(!file.exists()){
            file.mkdirs();
        }
        //解析request对象,获取文件上传项
        DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(fileItemFactory);

        List<FileItem> items = upload.parseRequest(request);
        for(FileItem item : items){
            //判断当前item对象是否为文件上传项
            if(!item.isFormField()){
                //获取文件名称
                String fileName = item.getName();
                String uuid = UUID.randomUUID().toString().replace("-","");
                fileName = uuid + "_" + fileName;
                //完成文件上传
                item.write(new File(path, fileName));
                //删除临时文件
                item.delete();
            }
        }
        return "success";
    }

(4)在WEB-INF下创建pages目录,建立success.jsp文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h3>文件上传成功</h3>
</body>
</html>

 (5)启动项目,选择文件,进行上传测试。

二、Spring MVC实现单文件上传

Spring MVC 框架中上传文件时将文件相关信息及操作封装到 MultipartFile 对象中,因此只需要使用 MultipartFile 类即可完成文件上传的操作。

(1)在index.jsp中添加表单。

<h3>Spring MVC方式文件上传</h3>
<form method="post" action="${pageContext.request.contextPath }/user/uploadFile02" enctype="multipart/form-data">
    选择文件:<input type="file" name="upload"><br>
    <input type="submit" value="上传">
</form>

(2)在web.xml中配置MultipartResolver,用于上传文件。

<!--  配置文件解析器对象,要求id名必须为 multipartResolver -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>

(3)添加处理的方法。

    @RequestMapping("/uploadFile02")
    public String uploadFile02(HttpServletRequest request, MultipartFile upload) throws Exception {
        System.out.println("Spring MVC方式文件上传");
        //获取文件上传的位置
        String path = request.getSession().getServletContext().getRealPath("/uploads");
        File file = new File(path);
        //文件夹不存在则创建文件夹
        if(!file.exists()){
            file.mkdirs();
        }
        //获取要上传的文件的名称
        String fileName = upload.getOriginalFilename();
        String uuid = UUID.randomUUID().toString().replace("-", "");
        fileName = uuid + "_" + fileName;
        upload.transferTo(new File(file, fileName));
        return "success";
    }

(4)启动项目,选择文件,进行上传测试.

 需要注意的是

a.表单中file标签的name属性名称必须和入参的变量名称相同,如下:

b. 配置文件解析器对象,要求id名必须为 multipartResolver

三、Spring MVC实现多文件上传

(1)在index.jsp中添加表单。

<h3>Spring MVC多文件上传</h3>
<form action="${pageContext.request.contextPath }/user/multiFileUpload"
      method="post" enctype="multipart/form-data">
    选择文件1:<input type="file" name="myFile"><br>
    文件描述1:<input type="text" name="description"><br />
    选择文件2:<input type="file" name="myFile"><br>
    文件描述2:<input type="text" name="description"><br />
    选择文件3:<input type="file" name="myFile"><br>
    文件描述3:<input type="text" name="description"><br />
    <input type="submit" value="提交">
</form>

(2)添加pojo类。

public class MultiFileMsg {
    private List<String> description;
    private List<MultipartFile> myFile;

    public List<String> getDescription() {
        return description;
    }

    public void setDescription(List<String> description) {
        this.description = description;
    }

    public List<MultipartFile> getMyFile() {
        return myFile;
    }

    public void setMyFile(List<MultipartFile> myFile) {
        this.myFile = myFile;
    }

    @Override
    public String toString() {
        return "MultiFileMsg{" +
                "description=" + description +
                ", myFile=" + myFile +
                '}';
    }
}

(3)添加处理方法

  @RequestMapping("/multiFileUpload")
    public String multiFileUpload(HttpServletRequest request, @ModelAttribute MultiFileMsg multiFileMsg) throws Exception {
        System.out.println("Spring MVC多文件上传");
        //获取文件上传的位置
        String realpath = request.getSession().getServletContext().getRealPath("/uploads");
        File targetDir = new File(realpath);
        //文件夹不存在则创建文件夹.
        if (!targetDir.exists()) {
            targetDir.mkdirs();
        }
        List<MultipartFile> files = multiFileMsg.getMyFile();
        for (int i = 0; i < files.size(); i++) {
            MultipartFile file = files.get(i);
            String fileName = file.getOriginalFilename();
            File targetFile = new File(realpath, fileName);
            // 上传
            try {
                file.transferTo(targetFile);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return "success";
    }

(4)修改success.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h3>文件上传成功</h3>
<table border="1px">
    <tr>
        <td>详情</td>
        <td>文件名</td>
    </tr>
<%--    <!-- 同时取两个数组的元素 -->--%>
    <c:forEach items="${multiFileMsg.description}" var="description"
               varStatus="loop">
        <tr>
            <td>${description}</td>
            <td>${multiFileMsg.myFile[loop.count-1].originalFilename}</td>
        </tr>
    </c:forEach>
    <!-- fileDomain.getMyfile().getOriginalFilename() -->
</table>
</body>
</html>

(5) 启动项目,选择文件,进行上传测试。

四、Spring MVC实现文件下载

利用程序实现下载需要以下两个报工作:

(1)Web 服务器需要告诉浏览器其所输出内容的类型不是普通文本文件或 HTML 文件,而是一个要保存到本地的下载文件,所以需要设置 Content-Type 的值为 application/x-msdownload。

(2)Web 服务器希望浏览器不直接处理相应的实体内容,而是由用户选择将相应的实体内容保存到一个文件中,所以要设置 Content-Disposition 报头。

该报头指定了接收程序处理数据内容的方式,在 HTTP 应用中只有 attachment 是标准方式,attachment 表示要求用户干预。在 attachment 后面还可以指定 filename 参数,该参数是服务器建议浏览器将实体内容保存到文件中的文件名称。

设置报头的示例如下:

response.setHeader("Content-Type", "application/x-msdownload");
response.setHeader("Content-Disposition", "attachment;filename="+filename);

(1)编写控制器类FileDownloadController

在FileDownloadController中有 3 个方法,即 showAllDownFiles 、downloadFiles和 toUTF8String。其中,showAllDownFiles 方法获取被下载的文件名称;downloadFiles方法执行下载功能;toUTF8String 方法是下载保存时中文文件名的字符编码转换方法。

@Controller
public class FileDownloadController {
    /**
     * 显示要下载的文件
     */
    @RequestMapping("showAllDownFiles")
    public String showAllDownFiles(HttpServletRequest request, Model model) {
        // 从 upload下载
        String realpath = request.getServletContext()
                .getRealPath("uploads");
        File dir = new File(realpath);
        File files[] = dir.listFiles();
        // 获取该目录下的所有文件名
        ArrayList<String> fileName = new ArrayList<String>();
        for (int i = 0; i < files.length; i++) {
            fileName.add(files[i].getName());
        }
        model.addAttribute("files", fileName);
        return "showAllFiles";
    }

    /**
     * 执行下载
     */
    @RequestMapping("downloadFile")
    public String downloadFile(@RequestParam String filename,
                       HttpServletRequest request, HttpServletResponse response) {
        String aFilePath = null; // 要下载的文件路径
        FileInputStream in = null; // 输入流
        ServletOutputStream out = null; // 输出流
        try {
            // 从workspace\.metadata\.plugins\org.eclipse.wst.server.core\
            // tmp0\wtpwebapps下载
            aFilePath = request.getServletContext().getRealPath("uploads");
            // 设置下载文件使用的报头
            response.setHeader("Content-Type", "application/x-msdownload");
            response.setHeader("Content-Disposition", "attachment; filename="
                    + toUTF8String(filename));
            // 读入文件
            in = new FileInputStream(aFilePath + "\\" + filename);
            // 得到响应对象的输出流,用于向客户端输出二进制数据
            out = response.getOutputStream();
            out.flush();
            int aRead = 0;
            byte b[] = new byte[1024];
            while ((aRead = in.read(b)) != -1 & in != null) {
                out.write(b, 0, aRead);
            }
            out.flush();
            in.close();
            out.close();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 下载保存时中文文件名的字符编码转换方法
     */
    public String toUTF8String(String str) {
        StringBuffer sb = new StringBuffer();
        int len = str.length();
        for (int i = 0; i < len; i++) {
            // 取出字符中的每个字符
            char c = str.charAt(i);
            // Unicode码值为0~255时,不做处理
            if (c >= 0 && c <= 255) {
                sb.append(c);
            } else { // 转换 UTF-8 编码
                byte b[];
                try {
                    b = Character.toString(c).getBytes("UTF-8");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                    b = null;
                }
                // 转换为%HH的字符串形式
                for (int j = 0; j < b.length; j++) {
                    int k = b[j];
                    if (k < 0) {
                        k &= 255;
                    }
                    sb.append("%" + Integer.toHexString(k).toUpperCase());
                }
            }
        }
        return sb.toString();
    }
}

(2)创建文件列表页面showAllFiles.jsp。

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
</head>
<body>
<table>
    <tr>
        <td>被下载的文件名</td>
    </tr>
    <!--遍历 model中的 files-->
    <c:forEach items="${files}" var="filename">
        <tr>
            <td>
                <a href="${pageContext.request.contextPath }/downloadFile?filename=${filename}">${filename}</a>
            </td>
        </tr>
    </c:forEach>
</table>
</body>
</html>

 (3)启动项目,选择文件,进行测试,访问:http://localhost:8080/SpringMVCStudy02_war/showDownFiles。执行结果如下,点击即可进行下载。

猜你喜欢

转载自blog.csdn.net/weixin_47382783/article/details/113600276