首页 > 解决方案 > java.net.http GET 和 apache httpclient GET 的区别

问题描述

我正在开发 Jboss 6.4.12。它发布简单的端点以下载图像,返回 javax.ws.rs.core.Response 的实例,其中设置实体为 java.io.file,内容类型和内容标题相应设置。

我用 apache httpclient 创建了简单的 GET:

    protected void checkStreamingOfFile(String variant, String id, Optional<Long> optFileSize, String contentType) {

        String endpoint = String.format(streamUrlTemplate, variant, id);

        try (CloseableHttpClient hc = HttpClients.createDefault()) {
            HttpGet get = new HttpGet(endpoint);
            CloseableHttpResponse resr = hc.execute(get);
            Assert.assertEquals(200, resr.getStatusLine().getStatusCode());
            Assert.assertEquals(contentType, resr.getEntity().getContentType().getValue());
            optFileSize.ifPresent(fileSize -> Assert.assertTrue(resr.getEntity().getContentLength() == fileSize));
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

并使用它从所述端点获取图像。它有效,端点返回图像并且响应根据上面的示例代码有效。然而在服务器日志中我得到:

21:18:48,020 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/web].[xxx.rest.RestGateway]] (http-127.0.0.1:8080-4) JBWEB000236: Servlet.service() for servlet xxx.rest.RestGateway threw exception: org.jboss.resteasy.spi.UnhandledException: Response is committed, can't handle exception
    at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:148) [resteasy-jaxrs-3.0.9.Final.jar:]
    at org.jboss.resteasy.core.SynchronousDispatcher.writeResponse(SynchronousDispatcher.java:432) [resteasy-jaxrs-3.0.9.Final.jar:]
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:376) [resteasy-jaxrs-3.0.9.Final.jar:]
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:179) [resteasy-jaxrs-3.0.9.Final.jar:]
    at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:220) [resteasy-jaxrs-3.0.9.Final.jar:]
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56) [resteasy-jaxrs-3.0.9.Final.jar:]
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51) [resteasy-jaxrs-3.0.9.Final.jar:]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [jboss-servlet-api_3.0_spec-1.0.2.Final-redhat-2.jar:1.0.2.Final-redhat-2]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:295) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at com.github.xxx.filters.EncodingFilter.doFilter(EncodingFilter.java:48) [xxx.web.jar:]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at com.github.xxx.filters.HttpCacheControlFilter.doFilter(HttpCacheControlFilter.java:105) [xxx.web.jar:]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at xxx.metrics.web.ActivityTrackingFilter.doFilter(ActivityTrackingFilter.java:130) [xxx.metrics.web.jar:]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at com.codahale.metrics.servlet.AbstractInstrumentedFilter.doFilter(AbstractInstrumentedFilter.java:104) [metrics-servlet.jar:3.1.2]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:231) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:149) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.jboss.modcluster.container.jbossweb.JBossWebContext$RequestListenerValve.event(JBossWebContext.java:91)
    at org.jboss.modcluster.container.jbossweb.JBossWebContext$RequestListenerValve.invoke(JBossWebContext.java:72)
    at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.5.12.Final-redhat-SNAPSHOT.jar:7.5.12.Final-redhat-SNAPSHOT]
    at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.5.12.Final-redhat-SNAPSHOT.jar:7.5.12.Final-redhat-SNAPSHOT]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:420) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at xxx.rest.core.authenticator.xxxFormAuthenticator.invoke(xxxFormAuthenticator.java:151) [classes:]
    at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:169) [jboss-as-web-7.5.12.Final-redhat-SNAPSHOT.jar:7.5.12.Final-redhat-SNAPSHOT]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:150) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.jboss.web.rewrite.RewriteValve.invoke(RewriteValve.java:466) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:102) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:854) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:656) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:926) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at java.lang.Thread.run(Thread.java:748) [rt.jar:1.8.0_151]
Caused by: ClientAbortException:  java.net.SocketException: Broken pipe (Write failed)
    at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:429) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:450) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:351) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:468) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:441) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:90) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.jboss.resteasy.plugins.server.servlet.HttpServletResponseWrapper$DeferredOutputStream.write(HttpServletResponseWrapper.java:46) [resteasy-jaxrs-3.0.9.Final.jar:]
    at org.jboss.resteasy.util.CommitHeaderOutputStream.write(CommitHeaderOutputStream.java:71) [resteasy-jaxrs-3.0.9.Final.jar:]
    at org.jboss.resteasy.plugins.providers.ProviderHelper.writeTo(ProviderHelper.java:126) [resteasy-jaxrs-3.0.9.Final.jar:]
    at org.jboss.resteasy.plugins.providers.FileProvider.writeIt(FileProvider.java:201) [resteasy-jaxrs-3.0.9.Final.jar:]
    at org.jboss.resteasy.plugins.providers.FileProvider.writeTo(FileProvider.java:123) [resteasy-jaxrs-3.0.9.Final.jar:]
    at org.jboss.resteasy.plugins.providers.FileProvider.writeTo(FileProvider.java:34) [resteasy-jaxrs-3.0.9.Final.jar:]
    at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.writeTo(AbstractWriterInterceptorContext.java:129) [resteasy-jaxrs-3.0.9.Final.jar:]
    at org.jboss.resteasy.core.interception.ServerWriterInterceptorContext.writeTo(ServerWriterInterceptorContext.java:62) [resteasy-jaxrs-3.0.9.Final.jar:]
    at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.proceed(AbstractWriterInterceptorContext.java:118) [resteasy-jaxrs-3.0.9.Final.jar:]
    at org.jboss.resteasy.plugins.interceptors.encoding.GZIPEncodingInterceptor.aroundWriteTo(GZIPEncodingInterceptor.java:100) [resteasy-jaxrs-3.0.9.Final.jar:]
    at org.jboss.resteasy.core.interception.AbstractWriterInterceptorContext.proceed(AbstractWriterInterceptorContext.java:122) [resteasy-jaxrs-3.0.9.Final.jar:]
    at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:99) [resteasy-jaxrs-3.0.9.Final.jar:]
    at org.jboss.resteasy.core.SynchronousDispatcher.writeResponse(SynchronousDispatcher.java:427) [resteasy-jaxrs-3.0.9.Final.jar:]
    ... 38 more
Caused by: java.net.SocketException: Broken pipe (Write failed)
    at java.net.SocketOutputStream.socketWrite0(Native Method) [rt.jar:1.8.0_151]
    at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111) [rt.jar:1.8.0_151]
    at java.net.SocketOutputStream.write(SocketOutputStream.java:155) [rt.jar:1.8.0_151]
    at org.apache.coyote.http11.InternalOutputBuffer.realWriteBytes(InternalOutputBuffer.java:706) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:450) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:351) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.coyote.http11.InternalOutputBuffer$OutputStreamOutputBuffer.doWrite(InternalOutputBuffer.java:730) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.coyote.http11.filters.IdentityOutputFilter.doWrite(IdentityOutputFilter.java:118) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.coyote.http11.InternalOutputBuffer.doWrite(InternalOutputBuffer.java:543) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.coyote.Response.doWrite(Response.java:594) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:424) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    ... 56 more

21:18:48,023 ERROR [org.apache.catalina.core.ContainerBase.[default-host]] (http-127.0.0.1:8080-4) JBWEB000313: Exception processing error page /error.json: java.lang.IllegalStateException: JBWEB000029: Cannot reset buffer after response has been committed
    at org.apache.catalina.connector.Response.resetBuffer(Response.java:694) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.catalina.connector.Response.resetBuffer(Response.java:714) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:520) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:375) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.jboss.web.rewrite.RewriteValve.invoke(RewriteValve.java:466) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:102) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:854) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:656) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:926) [jbossweb-7.5.19.Final-redhat-1.jar:7.5.19.Final-redhat-1]
    at java.lang.Thread.run(Thread.java:748) [rt.jar:1.8.0_151]

这么破的管子。我不知道如何防止它。但后来,出于好奇,我用 java.net 替换了 http 客户端。

    protected void checkStreamingOfFile_pureJava(String variant, String id, Optional<Long> optFileSize,
            String contentType) {

        String endpoint = String.format(streamUrlTemplate, variant, id);

        HttpResponse<byte[]> response;
        try {

            HttpRequest request = HttpRequest.newBuilder().uri(new URI(endpoint)).GET().build();
            response = HttpClient.newBuilder().proxy(ProxySelector.getDefault()).build().send(request,
                    HttpResponse.BodyHandlers.ofByteArray());

            Assert.assertEquals(200, response.statusCode());
            Assert.assertEquals(contentType, response.headers().firstValue(org.apache.http.HttpHeaders.CONTENT_TYPE).get());
            optFileSize.ifPresent(fileSize -> Assert.assertTrue(response.body().length == fileSize));
        } catch (IOException | InterruptedException | URISyntaxException e) {
            e.printStackTrace();
        } 

    }

并使用这个 http 客户端 - 我在日志中看不到任何错误。并且图像正确返回,断言通过。

问题:这两个 GET 请求有什么区别?为什么会发生这种可观察到的行为?

标签: javahttpjbossapache-httpclient-4.x

解决方案


推荐阅读