SpringMVC(6)文件上传
我们做一个上传图片的例子,页面(fileUpload.jsp)功能如下:
上传成功后即时显示上传的图片。
upload.jsp:
<body> <h3>文件上传</h3> <form action="/testAnnotationMVC_fileUpload/file/fileUpload2.jspx" method="post" enctype="multipart/form-data"> <input type="file" name="file" /> <input type="submit" value="上 传" /> </form> <h5>上传结果:</h5> <img alt="暂无图片" src="${fileUrl}" /> </body> |
在form表单中,enctype="mulitpart/form-data"是必须的,而且method必须是POST,不要忘记了。
特地搜了一下这个东西,下面是W3CSchool网站上的解释:
1)他的作用是设置表单的MIME编码,默认情况,这个编码格式是application/x-www-form-urlencoded,不能用于文件上传;只有使用了multipart/form-data,才能完整的传递文件数据。
2)enctype="multipart/form-data"是上传二进制数据; form里面的input的值以2进制的方式传过去。那么表单请求传到另一个jsp或servlet 里时是不能用request.getParameter()来获取到各个表单元素的值的。使用multipart/form-data上传时,发送的请求和一般的http不一样,需要转化后才能读其他参数。
此外,我们还需要导入两个依赖的commons包:
org.apache.commons.fileupload-1.2.0.jar
org.apache.commons.io-1.4.0.jar
一、传统文件流的方式
新建fileUploadController,有如下两个方法:
toFile() --- 跳转到上传的JSP页面
fileUpload() --- 文件上传的出的处理类
@Controller @RequestMapping("/file") public class fileUploadController { @RequestMapping("/toFile") //跳转到文件上传的JSP页面 public String toFileUpload() { return "fileUpload"; } @RequestMapping("/fileUpload") public String fileUpload(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request, ModelMap model) { //获得原始文件名 String fileName = file.getOriginalFilename(); System.out.println("fileName:"+ fileName); //新文件名 String newFileName = UUID.randomUUID()+fileName; //上传到什么地方 String path = "d:/upload/"; File f = new File(path); if(!f.exists())f.mkdirs(); if(!file.isEmpty()){ try { FileOutputStream fos = new FileOutputStream(path+newFileName); InputStream in = file.getInputStream(); int b = 0; while((b=in.read())!=-1){ fos.write(b); } fos.close(); in.close(); } catch (Exception e) { e.printStackTrace(); } } System.out.println("imgurl:"+ path+newFileName); //保存文件地址,用于JSP页面回显 model.addAttribute("fileUrl", path+newFileName); return "fileUpload"; } |
二、SpringMVC提供的MultiRequestResolver上传方式
Spring通过对Servlet API的HttpServletRequest接口精选扩展,使其能够很好的处理文件上传。扩展后的接口名为:
org.springframework.web.multipart.MultipartHttpServletRequest
MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest)(request);
然后就能正常读取参数: mRequest.getParameter("xxx");
我们再在fileUploadController里新增一个fileUpload2的方法:
@RequestMapping("/fileUpload2") public String fileUpload2(HttpServletRequest request,HttpServletResponse response) throws Exception{ CommonsMultipartResolver cmr = new CommonsMultipartResolver(request.getServletContext()); if(cmr.isMultipart(request)){ MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest)(request); Iterator<String> files = mRequest.getFileNames(); while(files.hasNext()){ MultipartFile mFile = mRequest.getFile(files.next()); if(mFile != null){ String fileName = UUID.randomUUID()+mFile.getOriginalFilename(); String path = "d:/upload/"+fileName; File localFile = new File(path); mFile.transferTo(localFile); request.setAttribute("fileUrl", path); } } } return "fileUpload"; } |
这样我们就完成了文件上传。