[SpringMVC from entry to actual combat tutorial] Chapter 4 SpringMVC upload and download

4. SpringMVC upload and download

    File upload: The essence is to copy files through IO, and copy local files to the server.
    
    File download: the essence is to copy files through IO, and copy the server-side files to the local.
    
    The file upload of the Spring MVC framework is based on the commons-fileupload component, and a further package is made on this component, which simplifies the code implementation of file upload and cancels the programming differences on different upload components.

4.1 Import file upload jar package

Method 1: Import jar package

 Method 2: maven dependency configuration

<dependencies>
    <!-- spring核心包-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.3.18.RELEASE</version>
    </dependency>
    <!-- springbean包 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>4.3.18.RELEASE</version>
    </dependency>
    <!-- springcontext包 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.3.18.RELEASE</version>
    </dependency>
    <!-- spring表达式包 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-expression</artifactId>
        <version>4.3.18.RELEASE</version>
    </dependency>
    <!-- springAOP包 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>4.3.18.RELEASE</version>
    </dependency>
    <!-- springAspects包 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>4.3.18.RELEASE</version>
    </dependency>
    <!-- spring对web的支持 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>4.3.18.RELEASE</version>
    </dependency>
    <!-- springwebMVC -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>4.3.18.RELEASE</version>
    </dependency>

    <!-- 配置javaweb环境 -->
    <!-- servlet-api -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
    <!-- jsp-api -->
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.1</version>
        <scope>provided</scope>
    </dependency>
    <!-- jstl -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>

    <!-- 上传组件包 -->
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.3.1</version>
    </dependency>
</dependencies>

4.2 configuration

  • SpringMVC provides direct support for file uploads, which is implemented through the plug-and-play MultipartResolver.

  • SpringMVC implements an implementation class with Commons FileUpload technology: CommonsMultipartResovler.

  • MultipartResovler is not installed by default in SpringMVC, so it cannot handle file uploads by default. If you want to use it, you need to configure CommonsMultipartResovler.

<?xml version="1.0" encoding="UTF-8"?>
<beans
        xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:p="http://www.springframework.org/schema/p"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- springmvc的注解式开发 -->
    <!-- 开启组件扫描 -->
    <context:component-scan base-package="com.newcapec.controller"/>

    <!-- MVC注解驱动 -->
    <mvc:annotation-driven/>

    <!-- 配置视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!-- 配置文件上传解析器 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 文件上传的属性设置 -->
        <!-- 设置上传文件的大小: 文件的总字节数 -->
        <!-- 
 			1KB = 1024B
			1MB = 1024KB
			1GB = 1024MB
			1TB = 1024GB
			...
		-->
        <property name="maxUploadSize" value="104857600"/>
        <!-- 设置上传的字符编码 -->
        <property name="defaultEncoding" value="utf-8"/>
        <!-- 设置缓存大小 -->
        <property name="maxInMemorySize" value="10240"/>
    </bean>
</beans>

4.3 Single file upload

4.3.1 Pages

index.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <base href="${pageContext.request.contextPath}/">
    <title>Title</title>
</head>
<body>
    <div style="text-align: center;">
        <h1>首页</h1>
        <p><a href="views/upload.jsp">文件上传</a></p>
        <p><a href="views/uploads.jsp">批量上传</a></p>
        <p><a href="views/show.jsp">文件展示</a></p>
        <p><a href="views/download.jsp">文件下载</a></p>
    </div>
</body>
</html>

success.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <base href="${pageContext.request.contextPath}/">
    <title>Title</title>
</head>
<body>
    <div style="text-align: center;">
        <h1>上传成功!!!</h1>
    </div>
</body>
</html>

upload.jsp:

  • The form submission type is changed to enctype="multipart/form-data".

  • The submission method is post request, method="post".

  • Add an input form element of type="file" to the form to select the file to be uploaded.

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <base href="${pageContext.request.contextPath}/">
    <title>Title</title>
</head>
<body>
    <div style="text-align: center">
        <h1>文件上传</h1>
        <!--
        在前端或页面中需要注意的:
        1.文件上传时提交的请求方法必须为post
        2.在form标签中enctype
        	enctype="application/x-www-form-urlencoded"为默认值:将数据转换为key/value格式,用于普通数据的提交
        	上传时需要修改enctype为enctype="multipart/form-data": 告知服务器请求中包含二进制的数据(文件)
        3.使用上传组件(上传表单元素) <input type="file">
        -->
        <form action="upload.do" method="post" enctype="multipart/form-data">
            <p>请选择文件:<input type="file" name="file"></p>
            <p><button>上传</button></p>
        </form>
    </div>
</body>
</html>

4.3.2 Controller

Add a parameter of type MultipartFile to the method of the Controller to receive the uploaded file.

@Controller
public class UploadController {

    /**
     * 文件上传: 将本地文件传输至服务端
     * 在springmvc中通过MultipartFile对象来接收上传的文件
     * MultipartFile对象就是通过文件上传解析器创建的
     */
    @RequestMapping("/upload.do")
    public String upload(MultipartFile file, HttpServletRequest request) throws IOException {
        /**
         * 处理上传文件:
         * 1.获取文件的基本信息
         * 2.指定文件的保存目录
         * 3.防止文件名称重复
         * 4.复制文件
         */
        //获取文件大小
        long fileSize = file.getSize();
        //获取文件名称
        String fileName = file.getOriginalFilename();
        System.out.println(fileSize);
        System.out.println(fileName);

        /**
         * 2.指定文件的保存目录
         * 第一种:当前项目目录下(不是工作空间中,而是项目发布后的目录)
         *      优点:属于项目内部资源,方便访问
         *      问题:文件在项目中,如果文件数据量大,不利于项目迁移
         * 第二种:服务器的文件系统中的目录
         *      优点:项目资源与上传文件分离
         *      问题:无法直接访问,需要配置虚拟目录,或搭建文件服务器
         */
        String rootPath = request.getServletContext().getRealPath("/upload");
        // String rootPath = "c:/upload";
        /**
         * 3.防止文件名称重复
         * 使用新建目录,分开存放文件
         * 使用UUID来生成新的文件名称
         */
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy");
        SimpleDateFormat sdf2 = new SimpleDateFormat("MM");
        Date today = new Date();
        String year = sdf1.format(today);
        String month = sdf2.format(today);

        File dir = new File(rootPath + "/" + year + "/" + month);
        if(!dir.exists()){
            dir.mkdirs();
        }

        String newName = UUID.randomUUID().toString().replace("-","") +
            fileName.substring(fileName.lastIndexOf("."));

        //目标文件
        File resultFile = new File(dir.getAbsolutePath() + "/" + newName);

        //4.文件传输
        file.transferTo(resultFile);
        System.out.println("文件上传成功...");
        return "success";
    }
}

Common methods in the MultipartFile class are as follows:

method effect
getOriginalFilename() Get the original name of the uploaded file
getSize() Get the byte size of the file, unit byte
transferTo(File dest) Store the file to the specified location through the i/o stream
getName() Get the name of the file component in the form
getContentType() Get file MIME type
getInputStream() get file stream
isEmpty() Is it empty

Handle uploaded files:

  • file save directory

    • The first type: under the current project directory (not in the workspace, but the directory after the project is released). Advantages: It belongs to the internal resources of the project and is easy to access; Problem: If the file is in the project, if the file has a large amount of data, it is not conducive to project migration;

    • The second type: a directory in the file system of the server. Advantages: separation of project resources and uploaded files; Problem: no direct access, need to configure a virtual directory, or build a file server;

  • Prevent duplicate file names.

    • Use a new directory to store files separately;

    • Use UUID to generate new file name;

4.4 Batch upload

uploads.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <base href="${pageContext.request.contextPath}/">
    <title>Title</title>
</head>
<body>
    <div style="text-align: center">
        <h1>批量上传</h1>
        <form action="uploadBatch.do" method="post" enctype="multipart/form-data">
            <p>请选择文件1:<input type="file" name="file"></p>
            <p>请选择文件2:<input type="file" name="file"></p>
            <p>请选择文件3:<input type="file" name="file"></p>
            <p><button>上传</button></p>
        </form>
    </div>
</body>
</html>

The parameter for receiving uploaded files is an array of MultipartFile type:

/**
  * 批量上传
  * 将MultipartFile对象定义为数组类型
  */
@RequestMapping("/uploadBatch.do")
public String uploadBatch(MultipartFile[] file) throws IOException {
    for (MultipartFile multipartFile : file) {
        multipartFile.transferTo(new File("c:/upload/" +  multipartFile.getOriginalFilename()));
    }
    System.out.println("批量上传成功...");
    return "success";
}

4.5 download

download.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <base href="${pageContext.request.contextPath}/">
    <title>Title</title>
</head>
<body>
    <div style="text-align: center">
        <a href="download.do?name=a.jpg">图片1</a>
        <a href="download.do?name=b.jpg">图片2</a>
        <a href="download.do?name=c.jpg">图片3</a>
        <a href="download.do?name=中文.txt">文件</a>
    </div>
</body>
</html>

Just set the response header:

@Controller
public class DownloadController {

    /**
     * 文件下载:将服务端的文件传输至客户端
     * 页面无需跳转,需要设置下载响应头
     */
    @RequestMapping("/download.do")
    public void download(String name, HttpServletResponse response) throws Exception {
        /**
         * 设置下载响应头
         * 1.content-disposition对应的值为attachment
         * 告知浏览器客户端,响应为回传文件(附件)
         * 2.设置下载时文件名称
         * "attachment;fileName="+name
         * 3.文件名称中文处理
         * 使用URLEncoder对象进行转码
         */
        // response.addHeader("content-disposition", "attachment");
        // response.addHeader("content-disposition", "attachment;fileName="+name);
        String filename = URLEncoder.encode(name,"UTF-8");
        response.addHeader("content-disposition", "attachment;fileName="+filename);

        //通过流进行文件传输
        FileInputStream inputStream = new FileInputStream("c:/upload/" + name);
        OutputStream outputStream = response.getOutputStream();

        byte[] buffer = new byte[1024];
        while(inputStream.read(buffer) != -1) {
            outputStream.write(buffer);
        }

        outputStream.flush();
        inputStream.close();
        outputStream.close();
    }
}

4.6 Loading resources

show.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <base href="${pageContext.request.contextPath}/">
    <title>Title</title>
</head>
<body>
    <div style="text-align: center;">
        <h1>图片展示</h1>
        <!--
			<p><img src="c:/upload/a.jpg"></p>
			错误写法
		-->
        <p><img src="upload/a.jpg"></p>
        <p><img src="/up/a.jpg"></p>
        <p><img src="/up/b.jpg"></p>
        <p><img src="/up/c.jpg"></p>
    </div>
</body>
</html>

The physical directory (the real directory in the hard disk) cannot be accessed on the page, so the corresponding virtual directory needs to be configured in the server:

4.6.1 Configuration in Eclipse

1. Double-click tomcat in the service list;

 2. Open the Modules configured by tomcat;

 3. Configure the virtual path in Web Modules;

4.6.2 Configuration in IDEA

1. Find the Run menu in the menu bar and select Edit Configurations;

 2. Select the Deployment tab, click the plus sign, and select External Source;

 3. Select the physical directory corresponding to the virtual path;

 4. Configure the virtual path in the Application context;

4.6.3 Configuration in tomcat

Find the <Host> tag in the server.xml file in the configuration directory conf, and add the following code to it. docBase is a physical directory, and path is a virtual path.

<Context docBase="c:\upload" path="/up" reloadable="true"/>

Guess you like

Origin blog.csdn.net/ligonglanyuan/article/details/125167791