Version: Next

文件上传与下载

新建maven模块 springmvc-09-file,添加web支持,更改artifacet增加lib目录,部署tomcat 配置springmvc_servlet.xml,配置web.xml,写一个测试用controller

概述

文件上传是项目开发中最常见的功能之一,springMVC可以很好的支持文件上传,但是SpringMVC上下文中默认没有装配MultipartResolver,因此默认情况下不能处理文件上传工作。我们必须在上下文中配置MultipartResolver

前端:为了能上传文件,必须将表单的method设置为POST,将enctype设置为multipart/form-data。这样浏览器才会把用户选择的文件以二进制数据发送给服务器

对form表单enctype属性的详细说明:

  • application/x-www=form-urlencoded:默认方式,只处理表单域中的value属性值,采用这种编码方式的表单将表单域中的值处理为URL编码方式
  • multipart/form-data:这种编码方式会以二进制流的方式来处理表单数据,这种编码方式会把文件的内容也封装到请求参数中,不会对字符编码
  • text/plain:除了把空格转换为+以外,其他字符都不做编码处理,这种方式使用直接通过表单发送邮件
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="提交">
</form>
  • SpringMVC为文件上传提供了直接的支持,这种支持是用即插即用的MultipartResolver实现的
  • SpringMVC使用Apache Commons FileUpload技术实现了一个MultipartResolver实现类:CommonsMultipartResolver
info

因此,SpringMVC的文件上传还依赖Apache Commons FileUpload组件

文件上传

  • 导入依赖

    • commons-fileupload,maven会自动导入它的依赖包commons-io
    <!--文件上传-->
    <dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.3</version>
    </dependency>
    <!--servlet-api导入高版本的-->
    <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    </dependency>
  • 配置bean——multipartResolver

    • bean id 必须为multipartResolver
    • defaultEncoding——请求编码格式,必须与前端页面的编码格式一致
    • maxUploadSize——上传文件大小限制,单位为字节 (10485760 = 10M)
    <bean id="multipartResolver"
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="defaultEncoding" value="utf-8"/>
    <property name="maxUploadSize" value="10485760"/>
    <property name="maxInMemorySize" value="40960"/>
    </bean>
  • CommonsMultipartFile的常用方法:

    • String getOriginalFIlename()——获取上传文件原名
    • InputStream getInputStream()——获取文件流
    • void transferTo(File dest)——将上传文件保存到一个目录文件中
  • index.jsp

    <form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="file">
    <input type="submit" value="提交">
    </form>
  • Controller

    • @RequestParam("file")name=file input标签得到的文件封装成CommonsMultipartFile对象
    • 批量上传将CommonsMultipartFile定义为数组即可
    @Controller
    public class FileController {
    @RequestMapping("/upload")
    public String fileUpload(@RequestParam("file") CommonsMultipartFile file,
    HttpServletRequest request) throws IOException {
    //获取文件名
    String uploadFileName = file.getOriginalFilename();
    //如果文件名为空,重定向到首页
    if ("".equals(uploadFileName)) {
    return "redirect:/index.jsp";
    }
    //文件名存在,打印文件名
    System.out.println("上传文件名: " + uploadFileName);
    //设置上传保存路径
    String path = request.getServletContext().getRealPath("/upload");
    //如果路径不存在,创建路径
    File realPath = new File(path);
    if (!realPath.exists()) {
    realPath.mkdir();
    }
    System.out.println("上传文件保存地址 " + realPath);
    InputStream inputStream = file.getInputStream();
    FileOutputStream outputStream = new FileOutputStream(new File(realPath, uploadFileName));
    int len = 0;
    byte[] buffer = new byte[1024];
    while ((len = inputStream.read(buffer)) != -1) {
    outputStream.write(buffer, 0, len);
    outputStream.flush();
    }
    outputStream.close();
    inputStream.close();
    return "redirect:/index.jsp";
    }
    }
  • 测试,文件被上传到/out/upload路径下

采用file.Transto保存上传文件

  • Controller

    • transferTo(new File(全路径))
    @RequestMapping("/upload2")
    public String fileUpload2(@RequestParam("file") CommonsMultipartFile file,
    HttpServletRequest request) throws IOException {
    //设置保存路径
    String path = request.getServletContext().getRealPath("/upload");
    File realPath = new File(path);
    if (!realPath.exists()) {
    realPath.mkdir();
    }
    System.out.println("上传文件保存地址 -> " + realPath);
    //通过CommonsMultipartFile的方法直接写文件
    file.transferTo(new File(realPath + "/" + file.getOriginalFilename()));
    return "redirect:/index.jsp";
    }
  • index.jsp,form表单action修改为/upload2

    <form action="/upload2" method="post" enctype="multipart/form-data">
    <input type="file" name="file">
    <input type="submit" value="提交">
    </form>

文件下载

输入输出流下载

  • Controller

    @RequestMapping("/download")
    public String downloads(HttpServletRequest request, HttpServletResponse response) throws IOException {
    String path = request.getServletContext().getRealPath("/upload");
    String fileName = "Sketchpad.png";
    //1. 设置response响应头
    response.reset();//设置页面不缓存,清空buffer
    response.setCharacterEncoding("UTF-8");
    response.setContentType("multipart/form-data"); //二进制传输
    //设置响应头
    response.setHeader("Content-Disposition",
    "attachment;fileName=" + URLEncoder.encode(fileName, "UTF-8"));
    File file = new File(path, fileName);
    //2 读取文件——输入流
    InputStream is = new FileInputStream(file);
    //3 写出文件——输出流
    OutputStream os = response.getOutputStream();
    byte[] buffer = new byte[1024];
    int len = 0;
    while ((len = is.read(buffer)) != -1) {
    os.write(buffer, 0, len);
    os.flush();
    }
    os.close();
    is.close();
    return null;
    }
  • index.jsp

    <a href="/download">点击下载</a>

直接访问静态资源

  • 路径 image-20200425161756228

  • index.jsp

    <a href="/statics/Sketchpad.png">点击下载</a>