简介:
Spring MVC为文件上传提供了直接的支持,这种支持使用即插即用的MultipartResolver实现的。Spring MVC 使用Apache Commons FileUpload技术实现了一个MultipartResolver实现类:CommonsMultipartResolver。因此,Spring MVC的文件上传还需依赖Apache Commons FileUpload的组件。
示例:Spring MVC的文件上传
uploadForm.jsp:
<html> <head> <title>文件上传</title> </head> <body> <h2>文件上传</h2> <form action="upload" enctype="multipart/form-data" method="post"> <table> <tr> <td>文件描述:</td> <td><input type="text" name="description"></td> </tr> <tr> <td>请选择文件:</td> <td><input type="file" name="file"></td> </tr> <tr> <td><input type="submit" value="上传"></td> </tr> </table> </form> </body> </html>
负责文件上传的表单的编码类型必须是“multipart/form-data”。
FileUploadController:
//上传文件会自动绑定到MultipartFile中 @RequestMapping(value="/upload",method=RequestMethod.POST) public String upload(HttpServletRequest request, @RequestParam("description") String description, @RequestParam("file") MultipartFile file) throws Exception{ System.out.println(description); //如果文件不为空,写入上传路径 if(!file.isEmpty()){ //上传文件路径 String path = request.getServletContext().getRealPath("/images/"); //上传文件名 String fileName = file.getOriginalFileName(); File filePath = new File(path,fileName); //判断路径是否存在,如果不存在就创建一个 if(!filePath.getParentFile().exists()){ filePath.getParentFile().mkdirs(); } //将文件上传保存到一个目标文件中 file.transferTo(new File(path+File.separator+FileName)); return "success"; }else{ return "error"; } }
说明: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)。将上传文件保存到另一个目标文件中。
★★★:Spring MVC上下文中默认没有装配MultipartResolver,因此默认情况下其不能处理文件上传工作。如果想使用Spring的文件上传功能,则需要在上下文中配置MultipartResolver。
springmvc-config.xml:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!--设置上传文件大小--> <property name="maxUploadSize"> <value>10485760</value> </property> <!-- 请求编码格式,必须和JSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 --> <property name="defaultEncoding"> <value>UTF-8</value> </property> </bean>
注意:CommonsMultipartResolver必须依赖于Apache commons FileUpload组件,所以需要将Apache的commons FileUpload的jar包放到项目的类路径下
示例:使用对象接收上传文件(开发中:上传的文件会作为对象的属性被保存。)
registerForm.jsp:
<html> <head> <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; //对应上传的file,类型为MultipartFile,上传文件会自动绑定到image属性当中 private MultipartFile image; //省略set/get方法 }
FileUploadController:
@RequestMapping(value="/register") public String register(HttpServletRequest request, @ModelAttribute User user, Model model) throws Exception{ System.out.print(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().exist()){ filePath.getParentFile().mkdirs(); } //将上传文件保存到一个目录文件中 user.getImage().transferTo(new File(path+File.separator+fileName)); //将用户添加到model model.addAttribute("user",user); //跳转到下载页面 return "userInfo"; }else{ return "error"; } }
userInfo.jsp页面:
<h3>文件下载</h3> <a href="download?fileName=${requestScope.user.image.originalFileName}"> ${requestScope.user.image.originalFileName} </a>
示例:Spring MVC的文件下载
文件下载比较简单,页面一个超链接,href属性等于要下载文件的文件名即可;但如果文件名是中文名,在某些浏览器会导致下载失败;Spring MVC 提供了一个ResponseEntity类型,它可以很方便地定义返回的HttpHeaders和HttpStatus
FIleUploadController:
@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 downloadFileName = new String(filename.getBytes("UTF-8"),"iso-8859-1"); //通知浏览器以attachment(下载方式)打开图片 headers.setContentDispositionFormData("attachment",downloadFileName); //application/octet-stream:二进制流数据(最常见的文件下载) headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); //201 HttpStatus.CREATED return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers,HttpStatus.CREATED); }
说明:download处理方法接收到页面传递的文件名filename后,使用Apache Commons FileUpload组件的FileUtils读取到项目的images文件夹下的该文件,并将其构成ResponseEntity对象返回客户端下载