Skip to content

13. 文件的上传下载

13.1. 创建项目

13.2. 添加依赖,修改pom.xml

添加common-fileupload(Apache)类库,从request中解析出文件内容

xml
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.12</version>
  <scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
  <version>3.0.1</version>
  <scope>provided</scope>
</dependency>

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
  <version>5.2.4.RELEASE</version>
</dependency>

<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
  <groupId>commons-fileupload</groupId>
  <artifactId>commons-fileupload</artifactId>
  <version>1.4</version>
</dependency>

13.3. 前端控制器(web.xml)

xml
<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <!--前端控制器-->
  <servlet>
    <servlet-name>DispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <!--默认的配置文件的名字applicationContext.xml-->
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>

  </servlet>

  <servlet-mapping>
    <servlet-name>DispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>


</web-app>

13.4. 配置multipartResolver

Springmvc.xml中配置使用什么类型的库解析request中的文件内容

1)使用Servlet原生的方式

2)common-fileupload

在springmvc中声明multipartResolver

xml
<?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:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
 http://www.springframework.org/schema/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd">


    <context:component-scan base-package="com.neuedu.mvc"></context:component-scan>

    <mvc:annotation-driven/>

    <!-- 使用Common-fileupload包解析  上传的文件   -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />

</beans>

13.5. 创建上传文件的表单

上传文件时form表单要求: 1 )method : post 2 )enctype: multipart/form-data

<%--
  Created by IntelliJ IDEA.
  User: root
  Date: 2020/4/1
  Time: 9:00
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>上传</title>
</head>
<body>

<!--
    上传文件时form表单要求:
    1 method : post
    2 enctype:  multipart/form-data

 -->

    <form action="${pageContext.request.contextPath}/upload_file"  method="post" enctype="multipart/form-data">

        上传文件1:<input type="file" name="myfile" /><br/>
        上传文件2:<input type="file" name="myfile" /><br/>

        <input type="submit" value="上传"/>

    </forma>


</body>
</html>
xml
!--指定使用common-fileupload类型的方式解析request中的文件内容-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!--设置允许上传的最大多少字节 -->
    <property name="maxUploadSize" value="2000"></property>
</bean>

13.6. 上传功能

1)将表单中的文件持久化的保存到服务器硬盘中,

2)记录到数据库中。

1 xxx 2020年4月1日08:43:35 96530565d35746b19bf5a5ee3251fdf8.txt a.txt

2 xxx 2020年4月1日08:43:35 86530565d35746b19bf5a5ee3251fdf8.txt a.txt

3 xxx 2020年4月1日08:43:35 76530565d35746b19bf5a5ee3251fdf8.txt b.txt

4 xxx 2020年4月1日08:43:35 66530565d35746b19bf5a5ee3251fdf8.txt ctxt

5 xxx 2020年4月1日08:43:35 596c08719709471697d0c39df87f8d6f.txt d.txt

java
package com.neuedu.mvc;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

/**
 * 项目:      spring-framework
 * 类名:       FileController
 * 创建时间:  2024/3/21 15:42
 * 描述 :
 * 作者 :     张金山
 * QQ :     314649444
 * Site:      https://jshand.gitee.io
 */
@Controller
public class FileController {


    public static final String  UPLOAD_DIR = "D:\\upload";

    /**
     *  http://127.0.0.1:8080/mvc/test
     *
     * @return
     */
    @ResponseBody
    @RequestMapping("test")
    String test(){
        return "success";
    }


    @RequestMapping("toupload")
    String toupload(){
        return "/upload.jsp";
    }


    @RequestMapping("upload_file")
    String uploadFile(MultipartFile myfile) throws IOException {


        String name = myfile.getName();
        String originalFilename = myfile.getOriginalFilename();
        long size = myfile.getSize();

        System.out.println("name = " + name);
        //  a.jpg   doc
        System.out.println("originalFilename = " + originalFilename);
        // jpg   doc
        String ext = originalFilename.substring(originalFilename.lastIndexOf("."));
        System.out.println("size = " + size);

        //将文件从临时目录转出到  dist目标为止
        //D:\\upload\\唯一的xxxxx.jpg
        String uuid  =UUID.randomUUID().toString().replace("-","");
        String  newFileName =   uuid + ext;
        File dist = new File(UPLOAD_DIR,newFileName);
        myfile.transferTo(dist);


        return "redirect:/list_file";
    }





    @RequestMapping("list_file")
    public String  listFile(Model model){


        File dir = new File(UPLOAD_DIR);
        File[] files = dir.listFiles();

        model.addAttribute("files",files);

        return "/file_list.jsp";
    }




}
html
<%--
  Created by IntelliJ IDEA.
  User: root
  Date: 2020/4/1
  Time: 9:00
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>上传</title>
</head>
<body>

<!--
    上传文件时form表单要求:
    1 method : post
    2 enctype:  multipart/form-data

 -->

<form action="${pageContext.request.contextPath}/upload_file"  method="post" enctype="multipart/form-data">

    上传文件1:<input type="file" name="myfile" /><br/>
<%--    上传文件1:<input type="file" name="myfile" /><br/>--%>
<%--    上传文件2:<input type="file" name="myfile" /><br/>--%>


    <input type="submit" value="上传"/>

    </forma>


</body>
</html>
html
<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2024/3/21
  Time: 16:17
  To change this template use File | Settings | File Templates.
--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

    <table cellpadding="0" cellspacing="0" border="1">
        <tr>
            <td> 序号  </td>
            <td> 文件名(硬盘中的)  </td>
            <td> 大小  </td>
        </tr>
        <c:forEach items="${files}" var="file" varStatus="status">
            <tr>
                <td> ${status.count}  </td>
                <td> ${file.name}  </td>
                <td> ${file.totalSpace}</td>
            </tr>
        </c:forEach>
    </table>




</body>
</html>

13.9. 下载

13.9.1. 展示列表

13.9.1.1. 控制的方法

java
/**
 * 列表展示文件
 * 1   xxx   2020年4月1日08:43:35     96530565d35746b19bf5a5ee3251fdf8.txt   a.txt
 * 2   xxx   2020年4月1日08:43:35     86530565d35746b19bf5a5ee3251fdf8.txt   a.txt
 * 3   xxx   2020年4月1日08:43:35     76530565d35746b19bf5a5ee3251fdf8.txt   b.txt
 * 4   xxx   2020年4月1日08:43:35     66530565d35746b19bf5a5ee3251fdf8.txt   ctxt
 * 5   xxx   2020年4月1日08:43:35     596c08719709471697d0c39df87f8d6f.txt   d.txt
 * @param  从Controller开始  http://127.0.0.1:8080/springmvc/filelist
 */
@RequestMapping(value = "/filelist")
public String upload(Model model) throws IOException {

    //查询数据库 返回list (文件)

    //暂时直接列表 D:\java1upload
    File uploadDir = new File(BASE_DIR);

    //所有文件的数组
    File[] files = uploadDir.listFiles();
    model.addAttribute("files",files);//将集合放到作用域中。

    return "/file/file_list.jsp";
}

13.9.1.2. Jsp列表

13.9.2. 提供下载的方法

根据文件名、id等条件查询对象的文件句柄并提供下载功能

13.9.2.1. 编码的形式自己读取文件并通过response响应

java
/**
     * http://127.0.0.1:8080/springmvc/download?filename=596c08719709471697d0c39df87f8d6f.txt
     * @param filename
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/download")
    public void download(String filename, HttpServletResponse response) throws IOException {

//        new File("D:\\java1upload\\",filename);
        File downFile = new File(BASE_DIR, filename);

        //告诉浏览器下面向浏览器发送附件
        response.setHeader("Content-Disposition","attachment;filename="+filename);
        ServletOutputStream os = response.getOutputStream();
        FileInputStream fis = new FileInputStream(downFile);

        int len = 0;
        byte[] buffer = new byte[1024];//缓存区
        while( (len = fis.read(buffer)) != -1){
            os.write(buffer,0,len);
            os.flush();
        }

        os.close();
        fis.close();
    }

Spring-web模块的ResponseEntity类快速的构建一个响应内容

java
/**
 *   http://127.0.0.1:8080/springmvc/download2?filename=596c08719709471697d0c39df87f8d6f.txt
 * @param filename
 * @param response
 * @return
 * @throws IOException
 */
@RequestMapping(value = "/download2")
public ResponseEntity download2(String filename, HttpServletResponse response) throws IOException {
    File downFile = new File(BASE_DIR, filename);


    ResponseEntity entity = ResponseEntity.ok().
            //mime
            header(HttpHeaders.CONTENT_TYPE,"application/octet-stream").
            //通知浏览器以什么方式处理响应结果(直接打开,附件下载)
            header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + downFile.getName() + "\"").
            //设置body中为文件资源
            body(new FileSystemResource(downFile));
    return entity;
}

Released under the MIT License.