快速解决commons-fileupload组件无法处理自定义head信息的bug

2022-10-20,,,,

jakarta commons fileupload组件可以处理http请求及响应,很多时候被用来处理文件上传,但是近期发现,当我们自定义文件上传、自己组装mime信息、文件上传时加入自定义head节点时,fileupload组件无法获得自定义的head节点,仔细分析了fileupload组件源代码后,发现核心方法在fileuploadbase文件的findnextitem方法中,问题在于fileupload组件解析完自定义的head节点后,却忘记传递到fileitemstreamimpl中了,稍作修订,即可修正该bug。
复制代码 代码如下:
/**解析文件列表
         * called for finding the nex item, if any.
         * @return true, if an next item was found, otherwise false.
         * @throws ioexception an i/o error occurred.
         */
        private boolean findnextitem() throws ioexception {
            if (eof) {
                return false;
            }
            if (currentitem != null) {
                currentitem.close();
                currentitem = null;
            }
            for (;;) {
                boolean nextpart;
                if (skippreamble) {
                    nextpart = multi.skippreamble();
                } else {
                    nextpart = multi.readboundary();
                }
                if (!nextpart) {
                    if (currentfieldname == null) {
                        // outer multipart terminated -> no more data
                        eof = true;
                        return false;
                    }
                    // inner multipart terminated -> return to parsing the outer
                    multi.setboundary(boundary);
                    currentfieldname = null;
                    continue;
                }
                fileitemheaders headers = getparsedheaders(multi.readheaders());
                if (currentfieldname == null) {
                    // we're parsing the outer multipart
                    string fieldname = getfieldname(headers);
                    if (fieldname != null) {
                        string subcontenttype = headers.getheader(content_type);
                        if (subcontenttype != null
                                &&  subcontenttype.tolowercase()
                                        .startswith(multipart_mixed)) {
                            currentfieldname = fieldname;
                            // multiple files associated with this field name
                            byte[] subboundary = getboundary(subcontenttype);
                            multi.setboundary(subboundary);
                            skippreamble = true;
                            continue;
                        }
                        string filename = getfilename(headers);
                        currentitem = new fileitemstreamimpl(filename,
                                fieldname, headers.getheader(content_type),
                                filename == null, getcontentlength(headers));
                        notifier.noteitem();
                        itemvalid = true;
                        return true;
                    }
                } else {
                    string filename = getfilename(headers);
                    if (filename != null) {
                             //这里代码要修订
                        //这是原来的代码,没有传入header
                        //currentitem = new fileitemstreamimpl(filename, currentfieldname,headers.getheader(content_type),false, getcontentlength(headers));
                        //这是新的代码,我们要传入header
                        currentitem = new fileitemstreamimpl(filename, currentfieldname,headers.getheader(content_type),false, getcontentlength(headers),headers);
                        notifier.noteitem();
                        itemvalid = true;
                        return true;
                    }
                }
                multi.discardbodydata();
            }
        }

 

            /**原始代码,存在丢失fileitemheaders信息的bug
             * creates a new instance.
             * @param pname the items file name, or null.
             * @param pfieldname the items field name.
             * @param pcontenttype the items content type, or null.
             * @param pformfield whether the item is a form field.
             * @param pcontentlength the items content length, if known, or -1
             * @throws ioexception creating the file item failed.
             */
            fileitemstreamimpl(string pname, string pfieldname,
                    string pcontenttype, boolean pformfield,
                    long pcontentlength) throws ioexception {
                name = pname;
                fieldname = pfieldname;
                contenttype = pcontenttype;
                formfield = pformfield;
                final iteminputstream itemstream = multi.newinputstream();
                inputstream istream = itemstream;
                if (filesizemax != -1) {
                    if (pcontentlength != -1
                            &&  pcontentlength > filesizemax) {
                        fileuploadexception e =
                            new filesizelimitexceededexception(
                                "the field " + fieldname
                                + " exceeds its maximum permitted "
                                + " size of " + filesizemax
                                + " characters.",
                                pcontentlength, filesizemax);
                        throw new fileuploadioexception(e);
                    }
                    istream = new limitedinputstream(istream, filesizemax) {
                        protected void raiseerror(long psizemax, long pcount)
                                throws ioexception {
                            itemstream.close(true);
                            fileuploadexception e =
                                new filesizelimitexceededexception(
                                    "the field " + fieldname
                                    + " exceeds its maximum permitted "
                                    + " size of " + psizemax
                                    + " characters.",
                                    pcount, psizemax);
                            throw new fileuploadioexception(e);
                        }
                    };
                }
                stream = istream;
            }

 

            /**创建fileitem,修订后的代码,解决丢失fileitemheaders信息的bug
             * @param pname
             * @param pfieldname
             * @param pcontenttype
             * @param pformfield
             * @param pcontentlength
             * @param headers
             * @throws ioexception
             */
            fileitemstreamimpl(string pname, string pfieldname,
                    string pcontenttype, boolean pformfield,
                    long pcontentlength,fileitemheaders headers) throws ioexception {
                name = pname;
                fieldname = pfieldname;
                contenttype = pcontenttype;
                formfield = pformfield;
                if(headers!=null){
                        this.headers = headers;
                }
                final iteminputstream itemstream = multi.newinputstream();
                inputstream istream = itemstream;
                if (filesizemax != -1) {
                    if (pcontentlength != -1
                            &&  pcontentlength > filesizemax) {
                        fileuploadexception e =
                            new filesizelimitexceededexception(
                                "the field " + fieldname
                                + " exceeds its maximum permitted "
                                + " size of " + filesizemax
                                + " characters.",
                                pcontentlength, filesizemax);
                        throw new fileuploadioexception(e);
                    }
                    istream = new limitedinputstream(istream, filesizemax) {
                        protected void raiseerror(long psizemax, long pcount)
                                throws ioexception {
                            itemstream.close(true);
                            fileuploadexception e =
                                new filesizelimitexceededexception(
                                    "the field " + fieldname
                                    + " exceeds its maximum permitted "
                                    + " size of " + psizemax
                                    + " characters.",
                                    pcount, psizemax);
                            throw new fileuploadioexception(e);
                        }
                    };
                }
                stream = istream;
            }

《快速解决commons-fileupload组件无法处理自定义head信息的bug.doc》

下载本文的Word格式文档,以方便收藏与打印。