Spring MVC learning summary (eight): file upload and download

1. The traditional way of uploading files

(1) Import the jar package

    <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) Write a file upload form in 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>

note:

a. The tag <input type="file"/> will display an input box and a button in the browser. The input box allows the user to fill in the file name and path name of the local file. The button allows the browser to open a file selection box for The user selects a file.

b. The enctype attribute of the form specifies the encoding method of the form data. This attribute has the following 3 values.

  • application/x-www-form-urlencoded: This is the default encoding method, which only processes the value attribute value in the form field.
  • multipart/form-data: This encoding method processes the form data in a binary stream, and encapsulates the content of the specified file in the file domain into the request parameters.
  • text/plain: This encoding method is only used when the action attribute of the form is in the form of "mailto:" URL. It is mainly suitable for sending emails directly through the form.

 

 (3) Add a method in 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) Create a pages directory under WEB-INF and create a success.jsp file

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

 (5) Start the project, select the file, and upload the test.

Two, Spring MVC realizes single file upload

In the Spring MVC framework, file-related information and operations are encapsulated in a MultipartFile object when uploading a file, so only the MultipartFile class is needed to complete the file upload operation.

(1) Add a form in 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) Configure MultipartResolver in web.xml for uploading files.

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

(3) The method of adding treatment.

    @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) Start the project, select the file, and upload the test.

 have to be aware of is

a. The name attribute name of the file tag in the form must be the same as the variable name of the input parameter, as follows:

b. Configure the file resolver object, the id name must be multipartResolver

Three, Spring MVC realizes multi-file upload

(1) Add a form in 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) Add pojo class.

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) Add processing method

  @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) Modify the success.jsp page

<%@ 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) Start the project, select the file, and upload the test.

Four, Spring MVC implementation file download

Downloading using the program requires the following two reports:

(1) The web server needs to tell the browser that the type of output content is not a normal text file or HTML file, but a download file to be saved locally, so you need to set Content- The value of Type is application/x-msdownload.

(2) The web server hopes that the browser does not directly process the corresponding entity content, but the user chooses to save the corresponding entity content to a file, so the Content-Disposition header should be set.

This header specifies the way the receiving program processes the data content. In HTTP applications, only attachment is the standard way, and attachment means that user intervention is required. You can also specify the filename parameter after attachment, which is the name of the file that the server recommends that the browser save the entity content to the file.

An example of setting the header is as follows:

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

(1) Write the controller class FileDownloadController

There are 3 methods in FileDownloadController, namely showAllDownFiles, downloadFiles and toUTF8String. Among them, the showAllDownFiles method obtains the name of the downloaded file; the downloadFiles method performs the download function; the toUTF8String method is the character encoding conversion method of the Chinese file name when downloading and saving.

@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) Create the file list page 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) Start the project, select the file, test it, and visit: http://localhost:8080/SpringMVCStudy02_war/showDownFiles . The execution result is as follows, click to download.

Guess you like

Origin blog.csdn.net/weixin_47382783/article/details/113600276