问题描述:
一般情况下,使用spring MVC上传文件的组件CommonsMultipartResolver,都需要在dispatcher-servlet.xml配置如下信息:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 文件限制512K --> <property name="maxUploadSize" value="524288" /> </bean>
但此处存在的一个弊端是:所有使用如下格式的获取,input上传文件,都会受到上述配置信息的限制,如果希望单独调整文件上传大小,还需再思考思考。
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; MultipartFile treatyFile = multipartRequest.getFile("treaty_url");
问题分析:
解决上述问题,有两种方式:
1、重新定义一个过滤器filter,截取传来的请求request,通过将请求转化为另外的上传类(不受spring MVC配置文件影响的类),同时重写org.springframework.web.multipart.commons.CommonsMultipartResolver中的isMultipart方法。但此法,需用新的上传文件类替换spring MVC的上传文件,过于繁琐,不可取。
2、重写原有spring MVC上传组件的方法,用于对特定请求做判断,如下:
/** * 1、覆盖父类方法,并重写prepareFileUpload方法,加参数request * 2、在新的prepareFileUpload方法中,获取请求路径,或特殊参数 * 3、根据特殊参数对上传文件最大值进行重复赋值 */ public class I2fCommonsMultipartResolver extends CommonsMultipartResolver { protected CommonsFileUploadSupport.MultipartParsingResult parseRequest(HttpServletRequest request)throws MultipartException{ String encoding = determineEncoding(request); FileUpload fileUpload = this.prepareFileUpload(encoding,request); try { List fileItems = ((ServletFileUpload) fileUpload).parseRequest(request); return parseFileItems(fileItems, encoding); } catch (FileUploadBase.SizeLimitExceededException ex) { throw new MaxUploadSizeExceededException(fileUpload.getSizeMax(), ex); } catch (FileUploadException ex) { throw new MultipartException( "Could not parse multipart servlet request", ex); } } protected FileUpload prepareFileUpload(String encoding,HttpServletRequest request) { FileUpload fileUpload = getFileUpload(); FileUpload actualFileUpload = fileUpload; // Use new temporary FileUpload instance if the request specifies // its own encoding that does not match the default encoding. if (encoding != null && !encoding.equals(fileUpload.getHeaderEncoding())) { actualFileUpload = newFileUpload(getFileItemFactory()); actualFileUpload.setHeaderEncoding(encoding); boolean isAddProduct = request.getRequestURI().contains("/product/addProductInfo.do") ||request.getRequestURI().contains("prodmanager/updateProductInfo.do"); if(isAddProduct){ actualFileUpload.setSizeMax(512 * 1024 * 10);//重新设置文件限制5M }else{ actualFileUpload.setSizeMax(fileUpload.getSizeMax()); } } return actualFileUpload; } }
同时,需将配置文件dispatcher-servlet.xml中的配置信息,改为你自己的类:
<bean id="multipartResolver" class="com.i2f.i2shopping.merchant.common.I2fCommonsMultipartResolver"> <!-- 文件限制512K --> <property name="maxUploadSize" value="524288" /> </bean>
此时,便对特定请求"/product/addProductInfo.do"与"prodmanager/updateProductInfo.do"文件上传进行单独限制为5M。
总结反思:
1、针对该问题,从大处讲就是“在一个大环境下,如何对特定请求进行属性设值”,解决问题的方式就是:查看spring MVC的具体源码,然后用新类重写源码的特定方法,必要时可以加上自己新的方法。需要注意的是,要保证不改变原有代码的功能。
2、从编程角度考虑,对于框架的使用,要去研究其源码,只有知道它是如何实现的,才能真正使用好他们。读懂源码的前提是:扎实的java基本知识、反射与设计模式的知识。同时,还需要耐心。