Springmvc文件上传实现流程解析
SpringMVC中对文件上传做了封装,我们可以更加方便的实现文件上传。从Spring3.1
开始,对于文件上传,提供了两个处理器:
- CommonsMultipartResolver
- StandardServletMultipartResolver
第一个处理器兼容性较好,可以兼容Servlet3.0之前的版本,但是它依赖了commons-fileupload这个第三方工具,所以如果使用这个,一定要添加commons-fileupload依赖。
第二个处理器兼容性较差,它适用于Servlet3.0之后的版本,它不依赖第三方工具,使用它,可以直接做文件上传。
CommonsMultipartResolver
添加依赖
commons-fileupload commons-fileupload 1.4
配置MultipartResolver
注意,这个Bean一定要有id,并且id必须是multipartResolver
创建jsp页面
注意文件上传请求是POST请求,enctype一定是multipart/form-data
开发文件上传接口
@Controller publicclassFileUploadController{ SimpleDateFormatsdf=newSimpleDateFormat("/yyyy/MM/dd/"); @RequestMapping("/upload") @ResponseBody publicStringupload(MultipartFilefile,HttpServletRequestreq){ Stringformat=sdf.format(newDate()); StringrealPath=req.getServletContext().getRealPath("/img")+format; Filefolder=newFile(realPath); if(!folder.exists()){ folder.mkdirs(); } StringoldName=file.getOriginalFilename(); StringnewName=UUID.randomUUID().toString()+oldName.substring(oldName.lastIndexOf(".")); try{ file.transferTo(newFile(folder,newName)); Stringurl=req.getScheme()+"://"+req.getServerName()+":"+req.getServerPort()+"/img"+format+newName; returnurl; }catch(IOExceptione){ e.printStackTrace(); } return"failed"; } }
这个文件上传方法中,一共做了四件事:
- 解决文件保存路径,这里是保存在项目运行目录下的img目录下,然后利用日期继续宁分类
- 处理文件名问题,使用UUID做新的文件名,用来代替旧的文件名,可以有效防止文件名冲突
- 保存文件
- 生成文件访问路径
这里还有一个小问题,在SpringMVC中,静态资源默认都是被自动拦截的,无法访问,意味着上传成功的图片无法访问,因此,还需要我们在SpringMVC的配置文件中,再添加如下配置:
完成之后,就可以访问jsp页面,做文件上传了。
当然,默认的配置不一定满足我们的需求,我们还可以自己手动配置文件上传大小等:
StandardServletMultipartResolver
这种文件上传方式,不需要依赖第三方jar(主要是不需要添加commons-fileupload这个依赖),但是也不支持Servlet3.0之前的版本。
使用StandardServletMultipartResolver,那我们首先在SpringMVC的配置文件中,配置这个Bean:
注意,这里Bean的名字依然叫multipartResolver
配置完成后,注意,这个Bean无法直接配置上传文件大小等限制。需要在web.xml中进行配置(这里,即使不需要限制文件上传大小,也需要在web.xml中配置multipart-config):
springmvc org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:spring-servlet.xml E:\\temp 1048576 1048576 4096 springmvc /
配置完成后,就可以测试文件上传了,测试方式和上面一样。
多文件上传
多文件上传分为两种,一种是key相同的文件,另一种是key不同的文件。
1key相同的文件
这种上传,前端页面一般如下:
主要是input节点中多了multiple属性。后端用一个数组来接收文件即可:
@RequestMapping("/upload2") @ResponseBody publicvoidupload2(MultipartFile[]files,HttpServletRequestreq){ Stringformat=sdf.format(newDate()); StringrealPath=req.getServletContext().getRealPath("/img")+format; Filefolder=newFile(realPath); if(!folder.exists()){ folder.mkdirs(); } try{ for(MultipartFilefile:files){ StringoldName=file.getOriginalFilename(); StringnewName=UUID.randomUUID().toString()+oldName.substring(oldName.lastIndexOf(".")); file.transferTo(newFile(folder,newName)); Stringurl=req.getScheme()+"://"+req.getServerName()+":"+req.getServerPort()+"/img"+format+newName; System.out.println(url); } }catch(IOExceptione){ e.printStackTrace(); } }
2key不同的文件
key不同的,一般前端定义如下:
这种,在后端用不同的变量来接收就行了:
@RequestMapping("/upload3") @ResponseBody publicvoidupload3(MultipartFilefile1,MultipartFilefile2,HttpServletRequestreq){ Stringformat=sdf.format(newDate()); StringrealPath=req.getServletContext().getRealPath("/img")+format; Filefolder=newFile(realPath); if(!folder.exists()){ folder.mkdirs(); } try{ StringoldName=file1.getOriginalFilename(); StringnewName=UUID.randomUUID().toString()+oldName.substring(oldName.lastIndexOf(".")); file1.transferTo(newFile(folder,newName)); Stringurl1=req.getScheme()+"://"+req.getServerName()+":"+req.getServerPort()+"/img"+format+newName; System.out.println(url1); StringoldName2=file2.getOriginalFilename(); StringnewName2=UUID.randomUUID().toString()+oldName2.substring(oldName2.lastIndexOf(".")); file2.transferTo(newFile(folder,newName2)); Stringurl2=req.getScheme()+"://"+req.getServerName()+":"+req.getServerPort()+"/img"+format+newName2; System.out.println(url2); }catch(IOExceptione){ e.printStackTrace(); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。