問題描述:
一般情況下,使用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基本知識、反射與設計模式的知識。同時,還需要耐心。