SpringMVC实现文件上传及下载
文件上传及下载在项目开发的过程中进场见到,这时一种比较常见的功能。springMVC可以很好的支持文件上传,如果想使用Spring的文件上传功能,则需要在上下文中配置MultipartResolver。
前景知识
- 文件上传在企业中十分常见
- 要想通过SpringMVC支持文件上传,需要配置好多东西
- 表单为了能上传文件,需要使用post方式提交,并且需要设置一个enctype
代码实现
在文件上传的问题上,由于电脑在传输过程中只能以二进制流的形式进行传输,所以可用两种方法来实现:一个是用流的形式,另外一个是用CommonsMultipartFile方法。
-
springmvc-servlet.xml
注意!这个bena的id必须为:multipartResolver , 否则上传文件会报400的错误
<?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.david.controller"/> <mvc:default-servlet-handler/> <mvc:annotation-driven/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <!--ID必须为multipartResolver,否则就400问题--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="utf-8"/> <property name="maxUploadSize" value="1048576"/> <property name="maxInMemorySize" value="40960"/> </bean> </beans>
-
需要导入文件上传的jar包,commons-fileupload , Maven会自动帮我们导入他的依赖包 commons-io包
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.3</version> </dependency> <!-- 我们会采用commons-io包中的实现类CommonsMultipartFile常用方法: String getOriginalFilename():获取上传文件的原名 InputStream getInputStream():获取文件流 void transferTo(File dest):将上传文件保存到一个目录文件中 -->
-
编写前端文件:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <body> <form enctype="multipart/form-data" method="post" action="${pageContext.request.contextPath}/upload2"> <input type="file" name="file"> <<input type="submit"> </form> <p><a href="${pageContext.request.contextPath}/download">下载</a></p><!--a标签链接到下载的链接--> </body> </html>
-
编写controller,必须加上@Requestparam,不然代码会出问题
我们这里用流和file.Transto都实现一次
并且也把文件下载也用代码在controller类中实现
package com.david.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.commons.CommonsMultipartFile; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.net.URLEncoder; @Controller public class FileUploadController { //上传方法:两个 //文件上传:流形式方法 @RequestMapping("/upload") @ResponseBody public String upload(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException { //1. 获取文件名 String filename = file.getOriginalFilename(); if ("".equals(filename)){//如果文件名为空,返回文件不存在 return "文件不存在"; } //2. 上传文件保存路径 String path = request.getServletContext().getRealPath("/upload"); File realPath = new File(path); if (!realPath.exists()){//如果文件不存在 realPath.mkdir();//创建一个新的目录 } //3. 上传文件 //文件改成流的形式 InputStream is = file.getInputStream();//得到file的输入流 //创建文件名为filename的realPath路径下的文件,并将其转换成文件输出流 FileOutputStream os = new FileOutputStream(new File(realPath, filename)); int len=0; byte[] buffer = new byte[1024];//创建一个缓冲区 while ((len=is.read(buffer))!=-1){// os.write(buffer,0,len); os.flush();//刷新 } //4. 关闭流,先开的后关 os.close(); is.close(); return "上传完毕"; } //文件上传:CommonsMultipartFile方法 @RequestMapping(value = "/upload2") @ResponseBody public String upload2(@RequestParam("file") CommonsMultipartFile file,HttpServletRequest request) throws IOException { String path = request.getServletContext().getRealPath("/upload");// //根据路径的创建文件 File realPath = new File(path); //判断文件是否存在,文件不存在就创建一个 if (!realPath.exists()){ realPath.mkdir(); } //transferTo:将文件写入到磁盘,参数就是一个文件 file.transferTo(new File(realPath+"/"+file.getOriginalFilename())); return "redirect:/index.jsp"; } //实现文件下载 /* 设置响应头--response响应头 读取本地文件--InputStream 写出文件--OutputStream 执行操作 关闭流(先开后关) */ @RequestMapping("/download") public String download(HttpServletResponse response) throws IOException { //要下载的图片路径:,服务器有没有强,一般下载都有自己公司的图床,地址; String path = "https://blog.kuangstudy.com/usr/themes/handsome/usr/img/sj/";//将图片路径转换成字符串 String filename = "5.jpg";//将文件名字转换成字符串 //设置项应头信息:固定代码,保存即可 response.reset(); //让页面不缓存 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); //输入流 FileInputStream input = new FileInputStream(file); //输出流 ServletOutputStream out = response.getOutputStream(); //执行操作 int len = 0; byte[] buffer = new byte[1024]; while ((len = input.read(buffer))!=-1){ out.write(buffer,0,len); out.flush(); } out.close(); input.close(); return null; } }
-
前端界面中的a标签用来跳转:
<a href="${pageContext.request.contextPath}/download">下载</a>
文件上传下载的方法有许多,这知识其中一种,其他的方法也可以