文件下载

  1. 访问资源时响应如果没有设置 Content-Disposition,浏览器默认按照 inline 值进行处理。inline 能显示就显示,不能显示就下载.

  2. 只需要修改相应头中 Context-Disposition=”attachment;filename=文件名”

    • attachment 下载,以附件形式下载.

    • filename=值就是下载时显示的下载文件名

      1
      res.setHeader("Content-Disposition", "attachment;filename=文件名");
  3. 通过apache提供的jar包来实现

实现步骤

  1. 导入jar包

    image-20191223144632313

  2. 在 jsp 中添加超链接,设置要下载文件。在 springmvc 中放行静态资源files文件夹

    image-20191223150013914

    image-20191223150054014

  3. 编写控制器方法

    image-20191223150230987

    image-20191223150904146

1
2
3
4
5
6
7
8
9
10
11
12
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="download?fileName=a.txt">下载</a>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.kylin.controller;

import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;

@Controller
public class DemoController {
@RequestMapping("/download")
public void download(String fileName,HttpServletResponse res,HttpServletRequest req) throws IOException{
//设置响应流中文件进行下载,attachment以附件形式下载,filename= 表示下载显示的下载文件名。
res.setHeader("Content-Disposition", "attachment;filename="+fileName);
// res.setHeader("Content-Disposition", "inline");
//把二进制流放入到响应体中.
ServletOutputStream os = res.getOutputStream();
String path = req.getServletContext().getRealPath("files");
System.out.println(path);
File file = new File(path, fileName);
byte[] bytes = FileUtils.readFileToByteArray(file);//读取文件成一个二进制数组
os.write(bytes);
os.flush();
os.close();
/*
InputStream is = new FileInputStream(file);
byte[] bytes = new byte[1024];
int len;
while ((len = is.read(bytes))!=-1){
os.write(bytes);
os.flush();
}
os.close();*/
}
}

文件上传

  1. 基于 apache 的 commons-fileupload.jar 完成文件上传.

  2. MultipartResovler 作用:

    • 把客户端上传的文件流转换成 MutipartFile 封装类.
    • 通过 MutipartFile 封装类获取到文件流
  3. 表单数据类型分类

    • 在form标签中的 enctype 属性控制表单类型
    • 默认值 application/x-www-form-urlencoded,普通表单数据.(少量文字信息)
    • text/plain 大文字量时使用的类型.邮件,论文
    • multipart/form-data 表单中包含二进制文件内容.
  4. 实现步骤

    • 导入 springmvc 包和 apache 文件上传 commons-fileuploadcommons-io 两个 jar

      image-20191223151909958

    • 编写 JSP 页面

      image-20191223152035933

    • 配置 springmvc.xm

      image-20191223184737733

    • 编写控制器类

      image-20191223190237272

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<form action="upload" enctype="multipart/form-data" method="post">
姓名:<input type="text" name="name"><br>
文件:<input type="file" name="file"><br>
<input type="submit" value="提交">
</form>
</body>
</html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?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
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--扫描注解-->
<context:component-scan base-package="com.kylin.controller"></context:component-scan>
<!--注解驱动-->
<!-- org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping -->
<!-- org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter -->
<mvc:annotation-driven></mvc:annotation-driven>
<!--静态资源-->
<!---->
<mvc:resources mapping="/js/**" location="/js/"></mvc:resources>
<mvc:resources mapping="/css/**" location="/css/"></mvc:resources>
<mvc:resources mapping="/images/**" location="/images/"></mvc:resources>
<mvc:resources location="/files/" mapping="/files/**"></mvc:resources>
<!--配置文件上传MultipartResovler解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--设置文件上传最大大小-50字节-->
<property name="maxUploadSize" value="50000"></property>
</bean>

<!--配置异常解析器-->
<bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<!--出现上传文件超过最大大小时,页面进行指定跳转-->
<prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">error.jsp</prop>
</props>
</property>
</bean>
</beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.kylin.controller;

import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

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

@Controller
public class DemoController {

@RequestMapping("/upload")
//MultipartFile 变量名必须于文件域的name属性值相同
public String upload(MultipartFile file,String name) throws IOException {
System.out.println("name:"+name);
//getName : 获取表单中文件组件的名字
//getOriginalFilename : 获取上传文件的原名
System.out.println(file.getName());
String fileName = file.getOriginalFilename();

String suffix = fileName.substring(fileName.lastIndexOf("."));//截取文件后缀名
String uuid = UUID.randomUUID().toString();//制造唯一文件名
FileUtils.copyInputStreamToFile(file.getInputStream(),new File("C:\\Data\\IDM\\Java学习\\"+uuid+suffix));
return "index.jsp";
}
}

总结

  • 利用了apache提供的两个jar包可以非常方便的使用其工具类进行文件的上传和下载。
  • 本章我写的不是很详细,如果有疑问可以参考前面JavaWeb-文件上传和JavaWeb-文件下载。apache提供的重点是对request.getInpustream()解析-FIleUpload。,其次是其工具类,不使用也可以按照原先IO流的对文件进行读写。我们所使用这两个jar包的根本原因是对requset.getInputStream的解析。
  • SpringMVC中我们使用的是MultipartResovler解析器,其所依赖的也是apache的这两个jar包。
  • 我们可以使用异常解析器对发生超出文件上传最大限制异常进行处理,当然也不仅仅使用于处理文件上传的异常,适用的是所遇到的各种异常对其处理。