在struts2中咱們上傳文件大於struts.multipart.maxSize設置的值時會拋出the request was rejected because its size (XXXX) exceeds the configured maximum (XXXX)異常,他是不能被國際化的,這信息對應用戶來講是很是不友好的,那任何處理? java
在struts2.2 中有兩個地方設置上傳文件大小: apache
一個是在攔截器fileUpload中設置 服務器
- <interceptor-ref name="fileUpload">
- <param name="maximumSize">1000000</param>
- </interceptor-ref>
一個是在struts2 自帶的文件default.properties中設置的(系統默認大小2M) 框架
struts.multipart.maxSize=2097152 jsp
這個能夠在struts.propertise 文件中修改 ide
那這兩個有什麼區別呢? .net
Struts2框架底層默認用的是apache的commons-fileupload組件對上傳文件進行接受處理。struts.multipart.maxSize設置的大小就是該處理時取用的值,在上傳文件以前系統會去比較文件的大小是否超過了該值,若是超過將拋出上述異常,commons-fileupload組件是不支持國際化的,因此咱們看到的異常都是默認的。 blog
fileUpload攔截器只是當文件上傳到服務器上以後,才進行的文件類型和大小判斷。 若是上傳的文件大小恰好這struts.multipart.maxSize與maximumSize 之間會拋出 key struts.messages.error.file.too.large 對應的異常信息,這個才支持國際化。那不是把struts.multipart.maxSize設很大,不就解決問題了嗎?非也! fileUpload攔截器只是當文件上傳到服務器上以後,才進行的文件類型和大小判斷,這樣會形成系統產生多餘沒用的文件。 ip
那該如何是好? get
其實解決的辦法有多種,我這裏介紹種最簡單的方法:
在struts2.2 org.apache.commons.fileupload.FileUploadBase.java 中咱們看到
- /**
- * Creates a new instance.
- * @param ctx The request context.
- * @throws FileUploadException An error occurred while
- * parsing the request.
- * @throws IOException An I/O error occurred.
- */
- FileItemIteratorImpl(RequestContext ctx)
- throws FileUploadException, IOException {
- if (ctx == null) {
- throw new NullPointerException("ctx parameter");
- }
-
- String contentType = ctx.getContentType();
- if ((null == contentType)
- || (!contentType.toLowerCase().startsWith(MULTIPART))) {
- throw new InvalidContentTypeException(
- "the request doesn't contain a "
- + MULTIPART_FORM_DATA
- + " or "
- + MULTIPART_MIXED
- + " stream, content type header is "
- + contentType);
- }
-
- InputStream input = ctx.getInputStream();
-
- if (sizeMax >= 0) {
- int requestSize = ctx.getContentLength();
- if (requestSize == -1) {
- input = new LimitedInputStream(input, sizeMax) {
- protected void raiseError(long pSizeMax, long pCount)
- throws IOException {
- FileUploadException ex =
- new SizeLimitExceededException(
- "the request was rejected because"
- + " its size (" + pCount
- + ") exceeds the configured maximum"
- + " (" + pSizeMax + ")",
- pCount, pSizeMax);
- throw new FileUploadIOException(ex);
- }
- };
- } else {
- ///問題就在這裏////////////////////////////////////
- if (sizeMax >= 0 && requestSize > sizeMax) {
- throw new SizeLimitExceededException(
- "the request was rejected because its size ("
- + requestSize
- + ") exceeds the configured maximum ("
- + sizeMax + ")",
- requestSize, sizeMax);
- }
- }
- }
-
- String charEncoding = headerEncoding;
- if (charEncoding == null) {
- charEncoding = ctx.getCharacterEncoding();
- }
-
- boundary = getBoundary(contentType);
- if (boundary == null) {
- throw new FileUploadException(
- "the request was rejected because "
- + "no multipart boundary was found");
- }
-
- notifier = new MultipartStream.ProgressNotifier(listener,
- ctx.getContentLength());
- multi = new MultipartStream(input, boundary, notifier);
- multi.setHeaderEncoding(charEncoding);
-
- skipPreamble = true;
- findNextItem();
- }
實際上他是把該異常信息設置爲Action級別的錯誤信息。
瞭解完這個就好辦了,咱們能夠在action中直接重寫ActionSupport的addActionError()方法,
- /**
-
- * 替換文件上傳中出現的錯誤信息
- *引用 import java.util.regex.Matcher;
- * import java.util.regex.Pattern;
- *
- * */
-
- @Override
-
- public void addActionError(String anErrorMessage) {
-
- //這裏要先判斷一下,是咱們要替換的錯誤,才處理
-
- if (anErrorMessage.startsWith("the request was rejected because its size")) {
-
- Matcher m = Pattern.compile("//d+").matcher(anErrorMessage);
-
- String s1 = "";
-
- if (m.find()) s1 = m.group();
-
- String s2 = "";
-
- if (m.find()) s2 = m.group();
-
- //偷樑換柱,將信息替換掉
- super.addActionError("你上傳的文件大小(" + s1 + ")超過容許的大小(" + s2 + ")");
- //也能夠改成在Field級別的錯誤
- // super.addFieldError("file","你上傳的文件大小(" + s1 + ")超過容許的大小(" + s2 + ")");
-
- } else {//不然按原來的方法處理
-
- super.addActionError(anErrorMessage);
- }
-
- }
這時這頁面增長
就能夠了。
作到這裏還有個問題,就是原來頁面上輸入的其餘文本內容也都不見了,也就是說params注入失敗。
這個是沒辦法的,由於這個異常是在文件上傳以前捕獲的,文件未上傳,同時params也爲注入,因此這時最好重定向到一個jsp文件,提示上傳失敗,而後重寫填寫相應信息。