当Apache Shiro遇上MultipartHttpServletRequest
2016-05-25 12:13
405 查看
摘要: 当Apache Shiro遇上SpringMVC MultipartHttpServletRequest
####项目是SpringMVC框架,配置了SpringMVC文件上传,同时使用了Apache Shiro。
####可以确定配置是无误的,表单也有enctype="multipart/form-data"属性。
####如下代码,当用MultipartHttpServletRequest接收文件上传请求时
####会报告如下错误
Current request is not of type [org.springframework.web.multipart.MultipartHttpServletRequest]: org.apache.shiro.web.servlet.ShiroHttpServletRequest@9a1d0ff
####暂时的解决方案如下
####fileUpload方法如下
####项目是比较陈旧的项目了,不确定错误原因是否是Shiro过滤文件上传引起的,不知道是否还有更好的解决方案(如通过某些配置可以解决问题),以后研究了此问题再来更新。
###===========================更新===========================
###===========================我是分割线===========================
###经过调试发现Apache Shiro和 SpringMVC MultipartHttpServletRequest是没有任何冲突的。
###之所以报告上面的错误是因为我忘记配置multipartResolver导致
###===========================再分割===========================
####问题虽然得到解决,但在调试过程中却发现了另一个问题,予以记录。
####通常,我们使用SpringMVC的时候,JSP页面的表单只要写上对应实体类的属性,在Controller层,SpringMVC是会自动为我们将属性封装成实体的
####但当我们牵涉到文件上传的时候,则有可能遭遇一个小陷阱。
####例如,我们有实体类_Product.java_如下
####对应的添加页面如下
####Controller层如下
####理论上你是不是在期待SpringMVC帮你把相关属性封装进Product,imgURL用于接收页面上对应的文件。
####遗憾的是你只会遇到_HTTP 400_错误,控制台也没有报告任何错误!
####造成错误的原因是SpringMVC帮你把相关属性封装进Product的时候,文件类型是无法用String接收的。
####所以你也该知道怎么解决了...
###===========================补充===========================
###===========================20160606补充===========================
####同理,当你用来接收页面数据的实体类包含Date类型,SpringMVC默认是没有相应转换器的,需要自己注册,在Controller中加入如下代码:
####项目是SpringMVC框架,配置了SpringMVC文件上传,同时使用了Apache Shiro。
####可以确定配置是无误的,表单也有enctype="multipart/form-data"属性。
####如下代码,当用MultipartHttpServletRequest接收文件上传请求时
@RequestMapping(value = "addOrUpdate", method = RequestMethod.POST) public String addOrUpdate(MultipartHttpServletRequest request) { // 业务逻辑 }
####会报告如下错误
Current request is not of type [org.springframework.web.multipart.MultipartHttpServletRequest]: org.apache.shiro.web.servlet.ShiroHttpServletRequest@9a1d0ff
####暂时的解决方案如下
public String addOrUpdate(MultipartHttpServletRequest request) { MultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext()); MultipartHttpServletRequest multipartRequest = resolver.resolveMultipart(request); List<String> uploadPaths = fileUpload(multipartRequest);
####fileUpload方法如下
private List<String> fileUpload(MultipartHttpServletRequest multipartRequest) { List<String> uploadPaths = new ArrayList<String>(); Map<String, MultipartFile> fileMap = multipartRequest.getFileMap(); Set<String> keys = fileMap.keySet(); for(String key : keys){ CommonsMultipartFile item = (CommonsMultipartFile)fileMap.get(key); if (!item.isEmpty()) { String fileName = item.getOriginalFilename();// 获得文件的完整路径 // 判断是否有图片上传 if (!("".equals(fileName)) && !(fileName == null)) { String menulogoPath = Global.getConfig("upload.logo.menu"); File dir = new File(menulogoPath); // 更改文件的保存路径,以防止文件重名的现象出现 if (!dir.exists()) { dir.mkdirs(); } String datetime = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()); String filenewName = datetime + "-" + fileName; File uploadedFile = new File(dir, filenewName); try { // 如果在该文件夹中已经有相同的文件,那么将其删除之后再重新创建(只适用于上传一张照片的情况) if (uploadedFile.exists()) { uploadedFile.delete(); } item.getFileItem().write(uploadedFile); uploadPaths.add(filenewName); System.out.println("return : " + filenewName); } catch (Exception e) { e.printStackTrace(); } } } } return uploadPaths; }
####项目是比较陈旧的项目了,不确定错误原因是否是Shiro过滤文件上传引起的,不知道是否还有更好的解决方案(如通过某些配置可以解决问题),以后研究了此问题再来更新。
###===========================更新===========================
###===========================我是分割线===========================
###经过调试发现Apache Shiro和 SpringMVC MultipartHttpServletRequest是没有任何冲突的。
###之所以报告上面的错误是因为我忘记配置multipartResolver导致
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="10485760"/> <property name="maxInMemorySize" value="4096"/> <property name="defaultEncoding" value="UTF-8"/> <property name="resolveLazily" value="true"/> </bean>
###===========================再分割===========================
####问题虽然得到解决,但在调试过程中却发现了另一个问题,予以记录。
####通常,我们使用SpringMVC的时候,JSP页面的表单只要写上对应实体类的属性,在Controller层,SpringMVC是会自动为我们将属性封装成实体的
####但当我们牵涉到文件上传的时候,则有可能遭遇一个小陷阱。
####例如,我们有实体类_Product.java_如下
public class Product { private String name; // 商品名称 private String imgURL; // 商品图片 // getter setter 省略 }
####对应的添加页面如下
<form action="" method="post" enctype="multipart/form-data"> <input name="name" type="text" value="" > <input name="imgURL" type="file" /> <input value="提交" type="submit"> </form>
####Controller层如下
@RequestMapping("") public String addProduct(Product p, MultipartFile imgURL) throws Exception { // 业务逻辑 return ""; }
####理论上你是不是在期待SpringMVC帮你把相关属性封装进Product,imgURL用于接收页面上对应的文件。
####遗憾的是你只会遇到_HTTP 400_错误,控制台也没有报告任何错误!
####造成错误的原因是SpringMVC帮你把相关属性封装进Product的时候,文件类型是无法用String接收的。
####所以你也该知道怎么解决了...
###===========================补充===========================
public String addOrUpdate(HttpServletRequest request) throws Exception { MultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext()); MultipartHttpServletRequest multipartRequest = resolver.resolveMultipart(request); Map<String,MultipartFile> fileMap = multipartRequest.getFileMap(); MultipartFile imageUrlFile = fileMap.get("imageUrlFile"); MultipartFile imageUrlHoverFile = fileMap.get("imageUrlHoverFile"); // 从multipartRequest得到MultipartFile的简单方式,spFiles是页面file的名称 // List<MultipartFile> list = multipartRequest.getFiles("spFiles") }
###===========================20160606补充===========================
####同理,当你用来接收页面数据的实体类包含Date类型,SpringMVC默认是没有相应转换器的,需要自己注册,在Controller中加入如下代码:
@InitBinder public void initBinder(WebDataBinder binder) { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); dateFormat.setLenient(false); binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true)); }
相关文章推荐
- Apache Isis 1.4.0 发布,领域驱动开发框架
- RH436 Day3 课后总结
- Linux快速构建apache web服务器
- Awstats处理多apache日志
- 安装perl模块小窍门
- Apache静态编译与动态编译的区别
- PHP+Apache在Windows 9x下的安装和配置
- Apache服务器配置全攻略
- Apache Web让JSP“动”起来
- Linux Apache+MySQL+PHP
- 建立Apache+PHP+MySQL数据库驱动的动态网站
- apache 环境下 php 的配置注意事项
- 在RedHat下安装apache jserv 1.1.2方法
- windows8.1下Apache+Php+MySQL配置步骤
- windows中PHP5.2.14以及apache2.2.16安装配置方法第1/2页
- 在Windows XP下安装Apache+MySQL+PHP环境
- 解析阿里云ubuntu12.04环境下配置Apache+PHP+PHPmyadmin+MYsql
- apache rewrite防盗链三例
- Apache 配置详解(最好的APACHE配置教程)
- Apache+php+mysql在windows下的安装与配置(图文)第1/2页