<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 63  文章 - 0  trackbacks - 0
    <2009年4月>
    2930311234
    567891011
    12131415161718
    19202122232425
    262728293012
    3456789

    常用鏈接

    留言簿(2)

    隨筆分類

    隨筆檔案

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    問題:

            struts2 使用jakarta 上傳文件時,如果上傳文件的大小超出commons fileupload(jakarta上傳文件還是依賴commons-fileupload)設置的大小就會在進入action以前拋出異常.
            如果想返回用戶的輸入界面(input),那么頁面原來的參數會丟失。

    首先看一下struts2 執行一個action的過程

    1.  將用戶請求發給org.apache.struts2.dispatcher.Dispatcher,
         wrapRequest(HttpServletRequest request, ServletContext servletContext)  方法會判斷是否"multipart/form-data",如果是建立一個multiPartRequest 的實例,并且建立MultiPartRequestWrapper

    寫道
    ...if (content_type != null && content_type.indexOf("multipart/form-data") != -1) {
           MultiPartRequest multi = getContainer().getInstance(MultiPartRequest.class);
           request = new MultiPartRequestWrapper(multi, request, getSaveDir(servletContext));
    } else {
           request = new StrutsRequestWrapper(request);
    }

     

    2. 建立 MultiPartRequestWrapper 時解析(parse) request,

    Java代碼
    1. public void parse(HttpServletRequest servletRequest, String saveDir)   
    2.             throws IOException {   
    3.         DiskFileItemFactory fac = new DiskFileItemFactory();   
    4.         // Make sure that the data is written to file   
    5.         fac.setSizeThreshold(0);   
    6.         if (saveDir != null) {   
    7.             fac.setRepository(new File(saveDir));   
    8.         }   
    9.   
    10.         // Parse the request   
    11.         try {   
    12.             ServletFileUpload upload = new ServletFileUpload(fac);   
    13.             upload.setSizeMax(maxSize);   
    14.             //upload 解析request并取得頁面參數   
    15.         List items = upload.parseRequest(createRequestContext(servletRequest));   
    16.         ......   
    17.           

     3.我們看一下ServletFileUpload(commons-fileupload v1.1.1) 的parseRequest做了什么

    Java代碼
    1. public List /* FileItem */ parseRequest(RequestContext ctx)   
    2.            throws FileUploadException {   
    3.        if (ctx == null) {   
    4.            throw new NullPointerException("ctx parameter");   
    5.        }   
    6.   
    7.        ArrayList items = new ArrayList();   
    8.        String contentType = ctx.getContentType();   
    9.   
    10.        if ((null == contentType)   
    11.            || (!contentType.toLowerCase().startsWith(MULTIPART))) {   
    12.            throw new InvalidContentTypeException(   
    13.                "the request doesn't contain a "  
    14.                + MULTIPART_FORM_DATA   
    15.                + " or "  
    16.                + MULTIPART_MIXED   
    17.                + " stream, content type header is "  
    18.                + contentType);   
    19.        }   
    20.        int requestSize = ctx.getContentLength();   
    21.           
    22.        if (requestSize == -1) {   
    23.            throw new UnknownSizeException(   
    24.                "the request was rejected because its size is unknown");   
    25.        }   
    26.        //關鍵就這里了,大小超出的異常,這里是所有上傳文件合計的大小,如果超出就拋出異常   
    27.        //這時上層是拿不到保存參數的items的   
    28.        if (sizeMax >= 0 && requestSize > sizeMax) {   
    29.            throw new SizeLimitExceededException(   
    30.                "the request was rejected because its size (" + requestSize   
    31.                + ") exceeds the configured maximum (" + sizeMax + ")",   
    32.                requestSize, sizeMax);   
    33.        }   
    34.   
    35.        String charEncoding = headerEncoding;   
    36.        if (charEncoding == null) {   
    37.            charEncoding = ctx.getCharacterEncoding();   
    38.        }   
    39.   
    40.        try {   
    41.            byte[] boundary = getBoundary(contentType);   
    42.            if (boundary == null) {   
    43.                throw new FileUploadException(   
    44.                        "the request was rejected because "  
    45.                        + "no multipart boundary was found");   
    46.            }   
    47.   
    48.            InputStream input = ctx.getInputStream();   
    49.   
    50.            MultipartStream multi = new MultipartStream(input, boundary);   
    51.            multi.setHeaderEncoding(charEncoding);   
    52.   
    53.            boolean nextPart = multi.skipPreamble();   
    54.            while (nextPart) {   
    55.                Map headers = parseHeaders(multi.readHeaders());   
    56.                String fieldName = getFieldName(headers);   
    57.                if (fieldName != null) {   
    58.                    String subContentType = getHeader(headers, CONTENT_TYPE);   
    59.                    if (subContentType != null && subContentType   
    60.                        .toLowerCase().startsWith(MULTIPART_MIXED)) {   
    61.                        // Multiple files.   
    62.                        byte[] subBoundary = getBoundary(subContentType);   
    63.                        multi.setBoundary(subBoundary);   
    64.                        boolean nextSubPart = multi.skipPreamble();   
    65.                        while (nextSubPart) {   
    66.                            headers = parseHeaders(multi.readHeaders());   
    67.                            if (getFileName(headers) != null) {   
    68.                                FileItem item =   
    69.                                        createItem(headers, false);   
    70.                                OutputStream os = item.getOutputStream();   
    71.                                try {   
    72.                                    multi.readBodyData(os);   
    73.                                } finally {   
    74.                                    os.close();   
    75.                                }   
    76.                                items.add(item);   
    77.                            } else {   
    78.                                // Ignore anything but files inside   
    79.                                // multipart/mixed.   
    80.                                multi.discardBodyData();   
    81.                            }   
    82.                            nextSubPart = multi.readBoundary();   
    83.                        }   
    84.                        multi.setBoundary(boundary);   
    85.                    } else {   
    86.                        FileItem item = createItem(headers,   
    87.                                getFileName(headers) == null);   
    88.                        OutputStream os = item.getOutputStream();   
    89.                        try {   
    90.                            multi.readBodyData(os);   
    91.                        } finally {   
    92.                            os.close();   
    93.                        }   
    94.                        items.add(item);   
    95.                    }   
    96.                } else {   
    97.                    // Skip this part.   
    98.                    multi.discardBodyData();   
    99.                }   
    100.                nextPart = multi.readBoundary();   
    101.            }   
    102.        } catch (IOException e) {   
    103.            throw new FileUploadException(   
    104.                "Processing of " + MULTIPART_FORM_DATA   
    105.                    + " request failed. " + e.getMessage());   
    106.        }   
    107.   
    108.        return items;   
    109.    }  

     4.這之后才開始逐個進入interceptor,見DefaultActionInvocation.invoke()

    Java代碼
    1. ....   
    2. //遞歸interceptor   
    3. if (interceptors.hasNext()) {   
    4.                 final InterceptorMapping interceptor = (InterceptorMapping) interceptors.next();   
    5.                 UtilTimerStack.profile("interceptor: "+interceptor.getName(),    
    6.                         new UtilTimerStack.ProfilingBlock<String>() {   
    7.                             public String doProfiling() throws Exception {   
    8.                                 resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);   
    9.                                 return null;   
    10.                             }   
    11.                 });   
    12.             } else {   
    13.                         //如果有errors,resultCode會得到‘input’   
    14.                 resultCode = invokeActionOnly();   
    15.             }   
    16. ...  

     5.我們的目標就是返回input并且保留頁面原來的參數,那么就要不要讓ServletFileUpload拋出異常,并且要讓strusts使用我們自己的jakart.

     6.寫自己的ServletFileUpload

    Java代碼
    1. /*  
    2.  * Copyright 2001-2005 The Apache Software Foundation  
    3.  *  
    4.  * Licensed under the Apache License, Version 2.0 (the "License");  
    5.  * you may not use this file except in compliance with the License.  
    6.  * You may obtain a copy of the License at  
    7.  *  
    8.  *     http://www.apache.org/licenses/LICENSE-2.0  
    9.  *  
    10.  * Unless required by applicable law or agreed to in writing, software  
    11.  * distributed under the License is distributed on an "AS IS" BASIS,  
    12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
    13.  * See the License for the specific language governing permissions and  
    14.  * limitations under the License.  
    15.  */  
    16. package com.infowarelab.newcentury.web.util;   
    17.   
    18. import java.io.IOException;   
    19. import java.io.InputStream;   
    20. import java.io.OutputStream;   
    21. import java.util.ArrayList;   
    22. import java.util.List;   
    23. import java.util.Map;   
    24.   
    25. import javax.servlet.http.HttpServletRequest;   
    26.   
    27. import org.apache.commons.fileupload.FileItem;   
    28. import org.apache.commons.fileupload.FileItemFactory;   
    29. import org.apache.commons.fileupload.FileUpload;   
    30. import org.apache.commons.fileupload.FileUploadException;   
    31. import org.apache.commons.fileupload.MultipartStream;   
    32. import org.apache.commons.fileupload.RequestContext;   
    33. import org.apache.commons.fileupload.servlet.ServletRequestContext;   
    34. import org.apache.log4j.Logger;   
    35.   
    36. /**  
    37.   * come from commons-fileupload  
    38.   * @author alfred  
    39.  */  
    40. public class ServletFileUpload extends FileUpload {   
    41.   
    42.     // ---------------------------------------------------------- Class methods   
    43.   
    44.     /**  
    45.      * Logger for this class  
    46.      */  
    47.     private static final Logger logger = Logger.getLogger(ServletFileUpload.class);   
    48.     private List<String> errors = new ArrayList<String>();   
    49.   
    50.     /**  
    51.      * Constructs an uninitialised instance of this class. A factory must be  
    52.      * configured, using <code>setFileItemFactory()</code>, before attempting  
    53.      * to parse requests.  
    54.      *   
    55.      * @see FileUpload#FileUpload(FileItemFactory)  
    56.      */  
    57.     public ServletFileUpload() {   
    58.         super();   
    59.     }   
    60.   
    61.     /**  
    62.      * Constructs an instance of this class which uses the supplied factory to  
    63.      * create <code>FileItem</code> instances.  
    64.      *   
    65.      * @see FileUpload#FileUpload()  
    66.      */  
    67.     public ServletFileUpload(FileItemFactory fileItemFactory) {   
    68.         super(fileItemFactory);   
    69.     }   
    70.     /**  
    71.      * overide parseRequest  
    72.      */  
    73.     public List /* FileItem */parseRequest(RequestContext ctx) throws FileUploadException {   
    74.         if (ctx == null) {   
    75.             throw new NullPointerException("ctx parameter");   
    76.         }   
    77.   
    78.         ArrayList items = new ArrayList();   
    79.         String contentType = ctx.getContentType();   
    80.   
    81.         if ((null == contentType) || (!contentType.toLowerCase().startsWith(MULTIPART))) {   
    82.             throw new InvalidContentTypeException("the request doesn't contain a " + MULTIPART_FORM_DATA + " or "  
    83.                     + MULTIPART_MIXED + " stream, content type header is " + contentType);   
    84.         }   
    85.         int requestSize = ctx.getContentLength();   
    86.   
    87.         if (requestSize == -1) {   
    88.             // throw new UnknownSizeException(   
    89.             // "the request was rejected because its size is unknown");   
    90.             logger.error("the request was rejected because its size is unknown");   
    91.             errors.add("the request was rejected because its size is unknown");   
    92.         }   
    93.   
    94.         String charEncoding = getHeaderEncoding();   
    95.         if (charEncoding == null) {   
    96.             charEncoding = ctx.getCharacterEncoding();   
    97.         }   
    98.   
    99.         try {   
    100.             byte[] boundary = getBoundary(contentType);   
    101.             if (boundary == null) {   
    102.                 // throw new FileUploadException(   
    103.                 // "the request was rejected because "   
    104.                 // + "no multipart boundary was found");   
    105.                 logger.error("the request was rejected because no multipart boundary was found");   
    106.                 errors.add("the request was rejected because no multipart boundary was found");   
    107.             }   
    108.   
    109.             InputStream input = ctx.getInputStream();   
    110.   
    111.             MultipartStream multi = new MultipartStream(input, boundary);   
    112.             multi.setHeaderEncoding(charEncoding);   
    113.   
    114.             boolean nextPart = multi.skipPreamble();   
    115.             while (nextPart) {   
    116.                 Map headers = parseHeaders(multi.readHeaders());   
    117.                 String fieldName = getFieldName(headers);   
    118.                 if (fieldName != null) {   
    119.                     String subContentType = getHeader(headers, CONTENT_TYPE);   
    120.                     if (subContentType != null && subContentType.toLowerCase().startsWith(MULTIPART_MIXED)) {   
    121.                         // Multiple files.   
    122.                         byte[] subBoundary = getBoundary(subContentType);   
    123.                         multi.setBoundary(subBoundary);   
    124.                         boolean nextSubPart = multi.skipPreamble();   
    125.                         while (nextSubPart) {   
    126.                             headers = parseHeaders(multi.readHeaders());   
    127.                             if (getFileName(headers) != null) {   
    128.                                 FileItem item = createItem(headers, false);   
    129.                                 OutputStream os = item.getOutputStream();   
    130.                                 try {   
    131.                                     multi.readBodyData(os);   
    132.                                 } finally {   
    133.                                     os.close();   
    134.                                 }   
    135.                                 items.add(item);   
    136.                             } else {   
    137.                                 // Ignore anything but files inside   
    138.                                 // multipart/mixed.   
    139.                                 multi.discardBodyData();   
    140.                             }   
    141.                             nextSubPart = multi.readBoundary();   
    142.                         }   
    143.                         multi.setBoundary(boundary);   
    144.                     } else {   
    145.                         FileItem item = createItem(headers, getFileName(headers) == null);   
    146.                         OutputStream os = item.getOutputStream();   
    147.                         try {   
    148.                             multi.readBodyData(os);   
    149.                         } finally {   
    150.                             os.close();   
    151.                         }   
    152.                         items.add(item);   
    153.                     }   
    154.                 } else {   
    155.                     // Skip this part.   
    156.                     multi.discardBodyData();   
    157.                 }   
    158.                 nextPart = multi.readBoundary();   
    159.             }   
    160.             // remove SizeLimitExceededException   
    161.             if (getSizeMax() >= 0 && requestSize > getSizeMax()) {   
    162.                 // throw new SizeLimitExceededException(   
    163.                 // "the request was rejected because its size (" + requestSize   
    164.                 // + ") exceeds the configured maximum (" + getSizeMax() + ")",   
    165.                 // requestSize, getSizeMax());   
    166.                 logger.error("the request was rejected because its size (" + requestSize   
    167.                         + ") exceeds the configured maximum (" + getSizeMax() + ")");   
    168.             }   
    169.         } catch (IOException e) {   
    170.             logger.error("Processing of " + MULTIPART_FORM_DATA + " request failed. " + e.getMessage());   
    171.             errors.add("Processing of " + MULTIPART_FORM_DATA + " request failed. " + e.getMessage());   
    172.             // throw new FileUploadException(   
    173.             // "Processing of " + MULTIPART_FORM_DATA   
    174.             // + " request failed. " + e.getMessage());   
    175.         }    
    176.            
    177.         return items;   
    178.     }   
    179.   
    180.     /**  
    181.      * @return the errors  
    182.      */  
    183.     public List<String> getErrors() {   
    184.         return errors;   
    185.     }   
    186.   
    187.     /**  
    188.      * @param errors the errors to set  
    189.      */  
    190.     public void setErrors(List<String> errors) {   
    191.         this.errors = errors;   
    192.     }   
    193.   
    194. }  

     

    7.copy org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest,只是import上面自己的ServletFileUpload.這樣就可以保存頁面的所有參數了。

    8.更改struts配置文件加入你自己的JakartaMultiReques

    Xml代碼
    1. <bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest"    
    2. ame="jakarta_yourself"    
    3.        class="com.xxxxx.util.JakartaMultiPartRequest"    
    4. cope="default" optional="true" />  

     9.更改struts.properties

    struts.multipart.parser=jakarta_yourself

    10.就OK啦

     

     

    posted on 2009-04-14 12:50 lanxin1020 閱讀(2228) 評論(0)  編輯  收藏 所屬分類: struts2
    主站蜘蛛池模板: 一本到卡二卡三卡免费高| 日韩亚洲国产高清免费视频| 国产一区二区免费视频| 我的小后妈韩剧在线看免费高清版| 伊伊人成亚洲综合人网7777| 亚洲一区电影在线观看| a在线视频免费观看在线视频三区| 2021在线永久免费视频| 久久精品国产精品亚洲下载| 亚洲一本到无码av中文字幕| 久久青草精品38国产免费| 亚洲国产香蕉人人爽成AV片久久 | 久久99国产亚洲高清观看首页| 亚洲乱理伦片在线观看中字| 久久99精品国产免费观看| 亚洲精品国产精品乱码不卞| igao激情在线视频免费| 亚洲AV无码久久寂寞少妇| www永久免费视频| 亚洲AV中文无码字幕色三| 1a级毛片免费观看| 亚洲精华国产精华精华液| 毛片免费视频在线观看| 亚洲日本香蕉视频| 16女性下面扒开无遮挡免费| 亚洲kkk4444在线观看| 国产h视频在线观看免费| 亚洲视频在线不卡| 真实国产乱子伦精品免费| 亚洲日本va午夜中文字幕一区| 中文字幕在线免费播放| 77777亚洲午夜久久多人| 免费人成在线观看网站品爱网 | 在线观看亚洲精品专区| 免费高清在线爱做视频| 亚洲综合一区无码精品| 亚洲福利精品一区二区三区 | 免费视频精品一区二区三区| 亚洲国产精品综合久久20| 野花高清在线观看免费完整版中文| 亚洲成av人无码亚洲成av人|