SpringMVC实现文件的上传和下载
文件的上传和下载能够直接使用Java中的IO流,Spring MVC为文件的上传也提供了直接的支持,但须要依赖Apache提供Commons FileUpload组件jar包html
SpringMVC框架提供了MultipartFile
对象,该对象表示上传的文件,要求变量名称必须和表单file标签的 name属性名称相同java
导入文件上传的jar包程序员
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency>
编写文件上传的JSP页面web
<h3>文件上传</h3> <form action="user/fileupload" method="post" enctype="multipart/form-data"> 选择文件:<input type="file" name="upload"/><br/> <input type="submit" value="上传文件"/> </form>
这里要注意spring
form的属性必须是multipart/form-data
,会把表单分红几个部分,存储不一样的值后端
必须使用post,由于使用get会把参数写在地址栏,地址栏的大小是有限制的浏览器
要提供一个选择文件的文本框服务器
文件上传是项目开发中最多见的功能。为了能上传文件,必须将表单的method
设置为POST
,并将enctype
设置为multipart/form-data
,只有在这样的状况下,浏览器才会把用户选择的文件以二进制数据发送给服务器app
一旦设置了enctype
为multipart/form-data
,浏览器即会采用二进制流的方式来处理表单数据,而对于文件上传的处理则涉及在服务器端解析原始的HTTP响应。在2003年,Apache Software Foundation发布了开源的Commons FileUpload
组件,其很快成为Servlet/JSP程序员上传文件的最佳选择框架
Servlet3.0规范已经提供方法来处理文件上传,但这种上传须要在Servlet中完成。而Spring MVC则提供了更简单的封装。
Spring MVC为文件上传提供了直接的支持,这种支持是用即插即用的MultipartResolver
实现的。Spring MVC使用Apache Commons FileUpload
技术实现了一个MultipartResolver
实现类:CommonsMultipartResolver
。所以,SpringMVC的文件上传还须要依赖Apache Commons FileUpload的组件
后端代码
/** * SpringMVC方式的文件上传 * * @param request * @return * @throws Exception */ @RequestMapping(value="/fileupload2") public String fileupload2(HttpServletRequest request,MultipartFile upload) throws Exception { System.out.println("SpringMVC方式的文件上传..."); // 先获取到要上传的文件目录 String path = request.getSession().getServletContext().getRealPath("/uploads"); // 建立File对象,一会向该路径下上传文件 File file = new File(path); // 判断路径是否存在,若是不存在,建立该路径 if(!file.exists()) { file.mkdirs(); } // 获取到上传文件的名称 String filename = upload.getOriginalFilename(); String uuid = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase(); // 把文件的名称惟一化 filename = uuid+"_"+filename; // 上传文件 upload.transferTo(new File(file,filename)); return "success"; }
Spring MVC会将上传的文件绑定到MultipartFile
对象中。MultipartFile提供了获取上传文件内容、文件名等方法。经过transferTo()
方法还能够将文件存储到硬件中,MultipartFile
对象中的经常使用方法以下:
byte[] getBytes():获取文件数据 String getContentType[]:获取文件MIME类型,如image/jpeg等 InputStream getInputStream():获取文件流 String getName():获取表单中文件组件的名字 String getOriginalFilename():获取上传文件的原名 Long getSize():获取文件的字节大小,单位为byte boolean isEmpty():是否有上传文件 void transferTo(File dest):将上传文件保存到一个目录文件中
配置文件解析器对象
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 上传文件大小上限,单位为字节(10MB) --> <property name="maxUploadSize"> <value>10485760</value> </property> <!-- 请求的编码格式,必须和jSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 --> <property name="defaultEncoding"> <value>UTF-8</value> </property> </bean>
在实际项目的开发中,不少时候上传的文件会做为对象的属性被保存。SpringMVC的处理也很是的简单
registerForm.jsp
<%@ 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>用户注册</title> </head> <body> <h2>用户注册</h2> <form action="register" enctype="multipart/form-data" method="post"> <table> <tr> <td>用户名:</td> <td><input type="text" name="username"></td> </tr> <tr> <td>请上传头像:</td> <td><input type="file" name="image"></td> </tr> <tr> <td><input type="submit" value="注册"></td> </tr> </table> </form> </body> </html>
user实体类
public class User implements Serializable{ private String username; private MultipartFile image; public User() { super(); } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public MultipartFile getImage() { return image; } public void setImage(MultipartFile image) { this.image = image; } }
Controller
@RequestMapping(value="/register") public String register(HttpServletRequest request,@ModelAttribute User user,Model model) throws Exception { System.out.println(user.getUsername()); //若是文件不为空,写入上传路径 if(!user.getImage().isEmpty()) { //上传文件路径 String path = request.getServletContext().getRealPath("/images/"); //上传文件名 String filename = user.getImage().getOriginalFilename(); File filepath = new File(path,filename); //判断路径是否存在,若是不存在就建立一个 if (!filepath.getParentFile().exists()) { filepath.getParentFile().mkdirs(); } //将上传文件保存到一个目标文件当中 user.getImage().transferTo(new File(path + File.separator + filename)); //将用户添加到model model.addAttribute("user", user); return "userInfo"; } else { return "error"; } }
文件下载比较简单,直接在页面给出了一个超连接,该连接href的属性等于要下载文件的文件名,就能够实现文件下载了。可是若是该文件的文件名为中文文件名,在某些早起的浏览器上就会致使下载失败;若是使用最新的Firefox、Chrome、Opera、Safari则均可以正常下载文件名为中文的文件了。
SpringMVC提供了一个ResponseEntity
类型,使用它能够很方便地定义返回的HttpHeaders
和HttpStatus
。如下代码演示文件的下载功能
@RequestMapping(value="/download") public ResponseEntity<byte[]> download(HttpServletRequest request, @RequestParam("filename") String filename, Model model)throws Exception { //下载文件路径 String path = request.getServletContext().getRealPath("/images/"); File file = new File(path + File.separator + filename); HttpHeaders headers = new HttpHeaders(); //下载显示的文件名,解决中文名称乱码问题 String downloadFielName = new String(filename.getBytes("UTF-8"),"iso-8859-1"); //通知浏览器以attachment(下载方式)打开图片 headers.setContentDispositionFormData("attachment", downloadFielName); //application/octet-stream : 二进制流数据(最多见的文件下载)。 headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.CREATED); }