加载文件时Tomcat + RichFaces 4.1异常

时间:2012-05-22 14:46:46

标签: jsf richfaces tomcat7

我已部署了我的webapp但由于某些原因,在尝试将文件加载到服务器时会出现一些异常,我不知道为什么会发生这种情况。有时当我尝试上传文件rich:fileUpload没有上传文件时,组件的进度条永远不会被填充,并且Tomcat的日志中会出现如下例外:

may 21, 2012 8:38:04 PM org.richfaces.request.MultipartRequest25 parseIfNecessary
SEVERE: Exception parsing multipart request: Request prolog cannot be read
org.richfaces.exception.FileUploadException: Exception parsing multipart request: Request prolog cannot be read
    at org.richfaces.request.MultipartRequestParser.parse(MultipartRequestParser.java:156)
    at org.richfaces.request.MultipartRequest25.parseIfNecessary(MultipartRequest25.java:77)
    at org.richfaces.request.MultipartRequest25.getParameter(MultipartRequest25.java:114)
    at com.sun.faces.context.RequestParameterMap.get(RequestParameterMap.java:75)
    at com.sun.faces.context.RequestParameterMap.get(RequestParameterMap.java:56)
    at java.util.Collections$UnmodifiableMap.get(Collections.java:1339)
    at com.sun.faces.application.view.MultiViewHandler.calculateRenderKitId(MultiViewHandler.java:220)
    at javax.faces.application.ViewHandlerWrapper.calculateRenderKitId(ViewHandlerWrapper.java:155)
    at com.sun.faces.context.FacesContextImpl.isPostback(FacesContextImpl.java:211)
    at javax.faces.context.FacesContextWrapper.isPostback(FacesContextWrapper.java:402)
    at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:188)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:116)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:964)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1824)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
Caused by: java.io.IOException: Request prolog cannot be read
    at org.richfaces.request.MultipartRequestParser.readProlog(MultipartRequestParser.java:270)
    at org.richfaces.request.MultipartRequestParser.initialize(MultipartRequestParser.java:172)
    at org.richfaces.request.MultipartRequestParser.parse(MultipartRequestParser.java:148)
    ... 30 more

may 21, 2012 8:38:04 PM org.richfaces.request.MultipartRequest25 parseIfNecessary
SEVERE: Exception parsing multipart request: Request prolog cannot be read
org.richfaces.exception.FileUploadException: Exception parsing multipart request: Request prolog cannot be read
    at org.richfaces.request.MultipartRequestParser.parse(MultipartRequestParser.java:156)
    at org.richfaces.request.MultipartRequest25.parseIfNecessary(MultipartRequest25.java:77)
    at org.richfaces.request.MultipartRequest25.getParameter(MultipartRequest25.java:114)
    at com.sun.faces.context.RequestParameterMap.get(RequestParameterMap.java:75)
    at com.sun.faces.context.RequestParameterMap.get(RequestParameterMap.java:56)
    at java.util.Collections$UnmodifiableMap.get(Collections.java:1339)
    at com.sun.faces.application.view.MultiViewHandler.calculateRenderKitId(MultiViewHandler.java:220)
    at javax.faces.application.ViewHandlerWrapper.calculateRenderKitId(ViewHandlerWrapper.java:155)
    at com.sun.faces.context.FacesContextImpl.isPostback(FacesContextImpl.java:211)
    at javax.faces.context.FacesContextWrapper.isPostback(FacesContextWrapper.java:402)
    at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:188)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:116)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:684)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:473)
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:402)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:329)
    at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:455)
    at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:399)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:191)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:964)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1824)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
Caused by: java.io.IOException: Request prolog cannot be read
    at org.richfaces.request.MultipartRequestParser.readProlog(MultipartRequestParser.java:270)
    at org.richfaces.request.MultipartRequestParser.initialize(MultipartRequestParser.java:172)
    at org.richfaces.request.MultipartRequestParser.parse(MultipartRequestParser.java:148)
    ... 33 more

may 21, 2012 8:38:04 PM org.richfaces.request.MultipartRequest25 parseIfNecessary
SEVERE: Exception parsing multipart request: Request prolog cannot be read
org.richfaces.exception.FileUploadException: Exception parsing multipart request: Request prolog cannot be read
    at org.richfaces.request.MultipartRequestParser.parse(MultipartRequestParser.java:156)
    at org.richfaces.request.MultipartRequest25.parseIfNecessary(MultipartRequest25.java:77)
    at org.richfaces.request.MultipartRequest25.getParameter(MultipartRequest25.java:114)
    at com.sun.faces.context.RequestParameterMap.get(RequestParameterMap.java:75)
    at com.sun.faces.context.RequestParameterMap.get(RequestParameterMap.java:56)
    at java.util.Collections$UnmodifiableMap.get(Collections.java:1339)
    at com.sun.faces.application.view.MultiViewHandler.calculateRenderKitId(MultiViewHandler.java:220)
    at javax.faces.application.ViewHandlerWrapper.calculateRenderKitId(ViewHandlerWrapper.java:155)
    at com.sun.faces.context.FacesContextImpl.isPostback(FacesContextImpl.java:211)
    at javax.faces.context.FacesContextWrapper.isPostback(FacesContextWrapper.java:402)
    at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:188)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:116)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:964)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1824)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
Caused by: java.io.IOException: Request prolog cannot be read
    at org.richfaces.request.MultipartRequestParser.readProlog(MultipartRequestParser.java:270)
    at org.richfaces.request.MultipartRequestParser.initialize(MultipartRequestParser.java:172)
    at org.richfaces.request.MultipartRequestParser.parse(MultipartRequestParser.java:148)
    ... 30 more

may 21, 2012 8:38:04 PM org.richfaces.request.MultipartRequest25 parseIfNecessary
SEVERE: Exception parsing multipart request: Request prolog cannot be read
org.richfaces.exception.FileUploadException: Exception parsing multipart request: Request prolog cannot be read
    at org.richfaces.request.MultipartRequestParser.parse(MultipartRequestParser.java:156)
    at org.richfaces.request.MultipartRequest25.parseIfNecessary(MultipartRequest25.java:77)
    at org.richfaces.request.MultipartRequest25.getParameter(MultipartRequest25.java:114)
    at com.sun.faces.context.RequestParameterMap.get(RequestParameterMap.java:75)
    at com.sun.faces.context.RequestParameterMap.get(RequestParameterMap.java:56)
    at java.util.Collections$UnmodifiableMap.get(Collections.java:1339)
    at com.sun.faces.application.view.MultiViewHandler.calculateRenderKitId(MultiViewHandler.java:220)
    at javax.faces.application.ViewHandlerWrapper.calculateRenderKitId(ViewHandlerWrapper.java:155)
    at com.sun.faces.context.FacesContextImpl.isPostback(FacesContextImpl.java:211)
    at javax.faces.context.FacesContextWrapper.isPostback(FacesContextWrapper.java:402)
    at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:188)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:116)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:684)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:473)
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:402)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:329)
    at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:455)
    at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:399)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:191)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:964)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1824)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
Caused by: java.io.IOException: Request prolog cannot be read
    at org.richfaces.request.MultipartRequestParser.readProlog(MultipartRequestParser.java:270)
    at org.richfaces.request.MultipartRequestParser.initialize(MultipartRequestParser.java:172)
    at org.richfaces.request.MultipartRequestParser.parse(MultipartRequestParser.java:148)
    ... 33 more

对可能发生的事情有任何想法?我在哪里可以开始寻找在我的应用上修复此问题?

欢呼声,

1 个答案:

答案 0 :(得分:3)

我的项目中有相同的堆栈跟踪。我可以解释为什么会发生这种情况以及解决问题的方法很少。

所以richfaces fileUpload组件假定还没有从其他地方读取多部分请求InputStream。但是,如果您的应用程序中有任何执行简单的过滤器 request.getParameter(anyParamName)这会强制多部分请求读取完整输入流并将所有内容放入request.getParts()集合中。

当richfaces fileupload尝试从输入流中读取内容时,它无法执行此操作,因为流游标位于末尾(这是在tomcat源中)并且只返回-1;这会导致richfaces认为它无法从流中读取任何内容。

要解决此问题,您可以删除强制多部分请求解析inputStream的所有过滤器。 此外,作为一个热修复,您可以尝试更改某些richfaces类,如MultipartRequest25MultipartRequestParser

我已为MultipartRequestParser添加了热修复程序,以检查请求是否已包含部件并尝试将部件解析为FileUploadParam。这非常hacky检查异常的消息,但它可以作为一个热修复。

jboss jira中存在未解决的问题,似乎是关于这个问题。你可以看看。我也在那里添加评论。 https://issues.jboss.org/browse/RF-13061

public void parse() throws FileUploadException {
    try {
        initialize();

        while (!sequenceMatcher.isEOF()) {
            readNext();
        }
    } catch (IOException e) {
        if(e.getMessage().equals(REQUEST_PROLOG_CANNOT_BE_READ)){
            //means it can not read request prolog. maybe application server already read everything and stores data in parts
            try {
                if(request.getParts()!=null && request.getParts().size()>0){
                    Collection<Part> parts = request.getParts();
                    //parts seem to be complete files so get the headers and so on here
                    //and create fileUploadItems from parts
                    for(Part part:parts){
                        String headersString = part.getHeader("content-disposition");
                        Multimap<String, String> headers = LinkedListMultimap.create();
                        String[] split = headersString.split("\r\n");
                        for (String headerString : split) {
                            parseParams(headerString, "; ", headers);
                        }
                        FileUploadParam param = createParam(headers);
                        if (param == null) {
                            continue;
                        }
                        param.create();
                        try{
                            int size = (int)part.getSize();
                            byte[] buf = new byte[size];
                            part.getInputStream().read(buf, 0, size);
                            param.handle(buf, size);
                        }finally{
                            param.complete();
                        }

                        if (param.isFileParam()) {
                            uploadedFiles.add(new UploadedFile25(param.getName(), param.getResource(), headers));
                        } else {
                            parametersMap.put(param.getName(), param.getValue());
                        }
                    }
                    //return from the method if everything was successfull
                    return;
                }
            } catch (Exception e1) {
                this.cancel();
                throw new IllegalStateException("Could get Parts from the request", e1);
            }
        }
        this.cancel();
        throw new FileUploadException(MessageFormat.format("Exception parsing multipart request: {0}", e.getMessage()), e);
    }
}

public void parse() throws FileUploadException { try { initialize(); while (!sequenceMatcher.isEOF()) { readNext(); } } catch (IOException e) { if(e.getMessage().equals(REQUEST_PROLOG_CANNOT_BE_READ)){ //means it can not read request prolog. maybe application server already read everything and stores data in parts try { if(request.getParts()!=null && request.getParts().size()>0){ Collection<Part> parts = request.getParts(); //parts seem to be complete files so get the headers and so on here //and create fileUploadItems from parts for(Part part:parts){ String headersString = part.getHeader("content-disposition"); Multimap<String, String> headers = LinkedListMultimap.create(); String[] split = headersString.split("\r\n"); for (String headerString : split) { parseParams(headerString, "; ", headers); } FileUploadParam param = createParam(headers); if (param == null) { continue; } param.create(); try{ int size = (int)part.getSize(); byte[] buf = new byte[size]; part.getInputStream().read(buf, 0, size); param.handle(buf, size); }finally{ param.complete(); } if (param.isFileParam()) { uploadedFiles.add(new UploadedFile25(param.getName(), param.getResource(), headers)); } else { parametersMap.put(param.getName(), param.getValue()); } } //return from the method if everything was successfull return; } } catch (Exception e1) { this.cancel(); throw new IllegalStateException("Could get Parts from the request", e1); } } this.cancel(); throw new FileUploadException(MessageFormat.format("Exception parsing multipart request: {0}", e.getMessage()), e); } }