SpringMVC_实现文件上传下载
文章目录
- 6. SpringMVC实现文件上传下载
- 6.1. 文件上传细节分析
- 6.1.1. 文件上传的3要素
- 6.1.2. 文件上传流程
- 6.1.4. 第三方工具
- 6.2. 文件上传
- 6.2.1. 上传的jsp页面
- 6.2.2. 配置文件解析器
- 6.3. 文件下载
- 6.3.1. 下载页面
- 6.3.2. 下载方法
6. SpringMVC实现文件上传下载
6.1. 文件上传细节分析
6.1.1. 文件上传的3要素
form表单的 enctype取值必须是:multipart/form-data
(默认值是:application/x-www-form-urlencoded)
enctype:是表单请求正文的类型
method属性取值必须是 Post
提供一个文件选择域
HTTP协议中新增的rfc1867协议,为 http 协议添加了上传功能。
根据 rfc1867协议规范,enctype=“multipart/form-data”, method=post, type=“file” 。这三个属性是必须的。multipart/form-data 是新增的编码类型,以提高二进制文件的传输效率。
-
enctype属性值
enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码。
值 | 描述 |
---|---|
application/x-www-form-urlencoded | 默认值。在发送前对所有字符进行编码为名称/值对 (将空格转换为 “+” 符号,特殊字符转换为 ASCII HEX 值)。 |
multipart/form-data | 不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。 |
text/plain | 空格转换为 “+” 加号,但不对特殊字符编码。 |
6.1.2. 文件上传流程
- 客户端的浏览器,如 Microsoft IE, Mozila Firefox, Chrome 等,按照此规范将用户指定的文件发送到服务器端的网页程序。
- 服务器端的网页程序,如 php, asp, jsp 等,可以按照此规范,解析出用户发送来的文件。经过编码发送给服务器。
- http server ,例如 tomcat ,已经支持此协议,可接收发送来的文件。
6.1.4. 第三方工具
文件上传过程比较复杂,但方式是固定的,因此出现了很多第三方的 http upload file 工具库,我们使用 Commons-fileupload 组件实现文件上传,需要导入该组件相应的支撑 jar 包:
- Commons-fileupload
- commons-io
commons-io 不属于文件上传组件的开发 jar 文件,但Commons-fileupload 组件从 1.1 版本开始,它
工作时需要 commons-io 包的支持。
使用maven依赖导入commons-fileupload依赖即可,commons-io会自动导入
<!--文件上传-->
<!-- -->
<dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.4</version>
</dependency>
6.2. 文件上传
- 添加上传的jsp
- 配置文件上传解析器
- 编写controller完成上传
6.2.1. 上传的jsp页面
- upload.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>文件上传</title>
</head>
<body><form action="/upload.do" method="post" enctype="multipart/form-data">名称:<input type="text" name="picname"/><br/>图片:<input type="file" name="uploadFile"/><br/><input type="submit" value="上传"/></form></body>
</html>
6.2.2. 配置文件解析器
springmvc.xml添加文件上传的解析器
<!-- 配置文件上传解析器 -->
<!-- id 的值是固定的-->
<bean id="multipartResolver"class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!-- 设定文件上传的最大值为5MB,5*1024*1024 --><property name="maxUploadSize" value="5242880"></property>
</bean>
6.2.3. controller完成文件上传
- 获取上传的文件名称
- 修改文件名,防止文件重名冲突
- 以日期区分保存文件的文件夹
- 将上传的文件保存到文件夹
//注意MultipartFile变量名必须和form表单的file的name属性一致
@RequestMapping("/upload")
public String uploadFile(String picname, MultipartFile uploadFile,HttpServletRequest request) throws IOException {if(uploadFile == null){return "error";}//保存文件名String fileName = "";//1.获取原始文件名String originalFilename = uploadFile.getOriginalFilename();//文件扩展名String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));//把文件加上随机数,防止重名被覆盖String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();//2. 修改文件名,防止文件重名冲突//文件名 = UUID_输入的文件名.扩展名 / UUID_原文件名.扩展名//判断是否输入文件名if(!StringUtils.isEmpty(picname)){fileName = uuid+"_"+picname+suffix;}else {fileName = uuid+"_"+originalFilename;}System.out.println(fileName);//3. 以日期区分保存文件的文件夹//3.1.获取文件路径ServletContext servletContext = request.getSession().getServletContext();String basePath = servletContext.getRealPath("/upload");//3.2.按日期创建文件夹,避免一个文件夹文件过多String datePath = new SimpleDateFormat("yyyy-mm-dd").format(new Date());//3.3.拼接存放文件的文件夹路径File dir = new File(basePath + "/" + datePath);//3.4.判断文件夹是否存在,不存在则创建目录if (!dir.exists()){dir.mkdir();}//4.将上传的文件保存到文件夹//使用 MulitpartFile 接口中方法,把上传的文件写到指定位置uploadFile.transferTo(new File(dir,fileName));return "success";
}
- 图片被上传到服务器指定位置
6.3. 文件下载
文件下载步骤:
- 准备下载页面
- 实现文件下载方法
6.3.1. 下载页面
download.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>文件下载</title>
</head>
<body><a href="/download?filename=年轻的我.jpg">年轻的我</a>
</body>
</html>
6.3.2. 下载方法
@RequestMapping("/download")
public String download(String filename, HttpServletResponse response){//没有下载的文件名可能是非法访问,直接返回nullif(StringUtils.isEmpty(filename)){return null;}System.out.println("用户要下载的文件:"+filename);//服务器存放的源文件File sourceFile = new File("H:\\upload\\2020-07-27\\照片.jpg");//数据写入到byte数组byte[] bytes = null;FileInputStream inputStream = null;OutputStream outputStream = null;try {//将下载的文件通过输入流读取inputStream = new FileInputStream(sourceFile);//创建写出数据的字节数组bytes = new byte[inputStream.available()];//将输入流数据转成字节inputStream.read(bytes);//下载的响应头header中只支持ASCII,文件名需要进行编码,否则下载不显示文件名filename = URLEncoder.encode(filename,"utf-8");//设置文件下载的响应头response.setHeader("Content-Disposition","attachment;filename="+filename);outputStream = response.getOutputStream();//将数据写出outputStream.write(bytes);//刷新缓冲区outputStream.flush();} catch (IOException e) {e.printStackTrace();throw new RuntimeException("文件下载异常!");}finally {//关闭输入流if(inputStream != null){try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}//关闭输出流try {outputStream.close();} catch (IOException e) {e.printStackTrace();}}return null;
}
SpringMVC_实现文件上传下载
文章目录
- 6. SpringMVC实现文件上传下载
- 6.1. 文件上传细节分析
- 6.1.1. 文件上传的3要素
- 6.1.2. 文件上传流程
- 6.1.4. 第三方工具
- 6.2. 文件上传
- 6.2.1. 上传的jsp页面
- 6.2.2. 配置文件解析器
- 6.3. 文件下载
- 6.3.1. 下载页面
- 6.3.2. 下载方法
6. SpringMVC实现文件上传下载
6.1. 文件上传细节分析
6.1.1. 文件上传的3要素
form表单的 enctype取值必须是:multipart/form-data
(默认值是:application/x-www-form-urlencoded)
enctype:是表单请求正文的类型
method属性取值必须是 Post
提供一个文件选择域
HTTP协议中新增的rfc1867协议,为 http 协议添加了上传功能。
根据 rfc1867协议规范,enctype=“multipart/form-data”, method=post, type=“file” 。这三个属性是必须的。multipart/form-data 是新增的编码类型,以提高二进制文件的传输效率。
-
enctype属性值
enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码。
值 | 描述 |
---|---|
application/x-www-form-urlencoded | 默认值。在发送前对所有字符进行编码为名称/值对 (将空格转换为 “+” 符号,特殊字符转换为 ASCII HEX 值)。 |
multipart/form-data | 不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。 |
text/plain | 空格转换为 “+” 加号,但不对特殊字符编码。 |
6.1.2. 文件上传流程
- 客户端的浏览器,如 Microsoft IE, Mozila Firefox, Chrome 等,按照此规范将用户指定的文件发送到服务器端的网页程序。
- 服务器端的网页程序,如 php, asp, jsp 等,可以按照此规范,解析出用户发送来的文件。经过编码发送给服务器。
- http server ,例如 tomcat ,已经支持此协议,可接收发送来的文件。
6.1.4. 第三方工具
文件上传过程比较复杂,但方式是固定的,因此出现了很多第三方的 http upload file 工具库,我们使用 Commons-fileupload 组件实现文件上传,需要导入该组件相应的支撑 jar 包:
- Commons-fileupload
- commons-io
commons-io 不属于文件上传组件的开发 jar 文件,但Commons-fileupload 组件从 1.1 版本开始,它
工作时需要 commons-io 包的支持。
使用maven依赖导入commons-fileupload依赖即可,commons-io会自动导入
<!--文件上传-->
<!-- -->
<dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.4</version>
</dependency>
6.2. 文件上传
- 添加上传的jsp
- 配置文件上传解析器
- 编写controller完成上传
6.2.1. 上传的jsp页面
- upload.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>文件上传</title>
</head>
<body><form action="/upload.do" method="post" enctype="multipart/form-data">名称:<input type="text" name="picname"/><br/>图片:<input type="file" name="uploadFile"/><br/><input type="submit" value="上传"/></form></body>
</html>
6.2.2. 配置文件解析器
springmvc.xml添加文件上传的解析器
<!-- 配置文件上传解析器 -->
<!-- id 的值是固定的-->
<bean id="multipartResolver"class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!-- 设定文件上传的最大值为5MB,5*1024*1024 --><property name="maxUploadSize" value="5242880"></property>
</bean>
6.2.3. controller完成文件上传
- 获取上传的文件名称
- 修改文件名,防止文件重名冲突
- 以日期区分保存文件的文件夹
- 将上传的文件保存到文件夹
//注意MultipartFile变量名必须和form表单的file的name属性一致
@RequestMapping("/upload")
public String uploadFile(String picname, MultipartFile uploadFile,HttpServletRequest request) throws IOException {if(uploadFile == null){return "error";}//保存文件名String fileName = "";//1.获取原始文件名String originalFilename = uploadFile.getOriginalFilename();//文件扩展名String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));//把文件加上随机数,防止重名被覆盖String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();//2. 修改文件名,防止文件重名冲突//文件名 = UUID_输入的文件名.扩展名 / UUID_原文件名.扩展名//判断是否输入文件名if(!StringUtils.isEmpty(picname)){fileName = uuid+"_"+picname+suffix;}else {fileName = uuid+"_"+originalFilename;}System.out.println(fileName);//3. 以日期区分保存文件的文件夹//3.1.获取文件路径ServletContext servletContext = request.getSession().getServletContext();String basePath = servletContext.getRealPath("/upload");//3.2.按日期创建文件夹,避免一个文件夹文件过多String datePath = new SimpleDateFormat("yyyy-mm-dd").format(new Date());//3.3.拼接存放文件的文件夹路径File dir = new File(basePath + "/" + datePath);//3.4.判断文件夹是否存在,不存在则创建目录if (!dir.exists()){dir.mkdir();}//4.将上传的文件保存到文件夹//使用 MulitpartFile 接口中方法,把上传的文件写到指定位置uploadFile.transferTo(new File(dir,fileName));return "success";
}
- 图片被上传到服务器指定位置
6.3. 文件下载
文件下载步骤:
- 准备下载页面
- 实现文件下载方法
6.3.1. 下载页面
download.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>文件下载</title>
</head>
<body><a href="/download?filename=年轻的我.jpg">年轻的我</a>
</body>
</html>
6.3.2. 下载方法
@RequestMapping("/download")
public String download(String filename, HttpServletResponse response){//没有下载的文件名可能是非法访问,直接返回nullif(StringUtils.isEmpty(filename)){return null;}System.out.println("用户要下载的文件:"+filename);//服务器存放的源文件File sourceFile = new File("H:\\upload\\2020-07-27\\照片.jpg");//数据写入到byte数组byte[] bytes = null;FileInputStream inputStream = null;OutputStream outputStream = null;try {//将下载的文件通过输入流读取inputStream = new FileInputStream(sourceFile);//创建写出数据的字节数组bytes = new byte[inputStream.available()];//将输入流数据转成字节inputStream.read(bytes);//下载的响应头header中只支持ASCII,文件名需要进行编码,否则下载不显示文件名filename = URLEncoder.encode(filename,"utf-8");//设置文件下载的响应头response.setHeader("Content-Disposition","attachment;filename="+filename);outputStream = response.getOutputStream();//将数据写出outputStream.write(bytes);//刷新缓冲区outputStream.flush();} catch (IOException e) {e.printStackTrace();throw new RuntimeException("文件下载异常!");}finally {//关闭输入流if(inputStream != null){try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}//关闭输出流try {outputStream.close();} catch (IOException e) {e.printStackTrace();}}return null;
}
发布评论