SpringMVC使用MultipartResolver实现文件的上传和下载
原文:http://www.bieryun.com/1120.html
使用MVC框架实现文件上传和下载
文件上传是项目开发中最常见的功能。为了能上传文件,必须将表单的method设置为POST,并将enctype设置为multipart/form-data。
只有在这样的情况下,浏览器才会把用户选择的文件以二进制数据发送给服务器。
Spring MVC使用Apache Commons FileUpload技术实现了一个MultipartResolver实现类:CommonsMultipartResolver。
因此,SpringMVC的文件上传还需要依赖Apache Commons FileUpload的组件。
<!-- 上传组件包 --> <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> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.9</version> </dependency>
表单:
xml文件配置:
<!-- 配置文件上传,如果没有使用文件上传可以不用配置,当然如果不配,那么配置文件中也不必引入上传组件包 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 默认编码 --> <property name="defaultEncoding" value="utf-8"/> <!-- 文件大小最大值 --> <property name="maxUploadSize" value="10485760000"/> <!-- 内存中的最大值 --> <property name="maxInMemorySize" value="40960"/> <!-- 启用是为了推迟文件解析,以便捕获文件大小异常 --> <property name="resolveLazily" value="true"/> </bean> <!-- 定义跳转的文件的前后缀 ,视图模式配置 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 这里的配置我的理解是自动给后面action的方法return的字符串加上前缀和后缀,变成一个 可用的url地址 --> <property name="prefix" value="/WEB-INF/content/"/> <property name="suffix" value=".jsp"/> </bean>
controller层写一个FileUploadController
可以将文件上传写成一个utils
@Controller public class FileUploadController { @RequestMapping(value="/{formName}") public String loginForm(@PathVariable String formName) { // 动态跳转页面 return formName; } //上传文件会自动绑定到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));
//因为xml中已经配置了前后缀,所以return "success" 返回的是页面,写了一个上传成功和失败的页面 return "success"; } else { return "lose"; } } //可以写成一个上传文件的方法,作为服务增加时调用 @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 "lose"; } } @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); }
实体类,实现序列化,和一个MultipartFile类型用来接收文件