一个人想从InputStream中放入数据,但是Jersey无法自动检测数据长度,也不能预设Content-Length标头.
A want to put data from InputStream, but Jersey can not detect data length automatically and not preset Content-Length header.
Response destinationResponse = responseWebTarget .request() .header(HEADER_X_AUTH_TOKEN, cmd.getOptionValue("dat")) .put(Entity.entity(inputStream, MediaType.APPLICATION_OCTET_STREAM))结果是:
INFO: 2 * Sending client request on thread main 2 > PUT 192.168.1.10:8080/v1/AUTH_system/08138784704e2/test 2 > Content-Type: application/octet-stream 2 > X-Auth-Token: AUTH_tka2d071e5ba3e46e58cbbc3bdcc57bc70我知道数据长度,并尝试手动添加标头:
I know data length and try to add header manually:
Object contentLength = sourceResponse.getHeaders().get(HTTP.CONTENT_LEN).get(0); Response destinationResponse = responseWebTarget .request() .header(HTTP.CONTENT_LEN, contentLength) .header(HEADER_X_AUTH_TOKEN, cmd.getOptionValue("dat")) .put(Entity.entity(is, MediaType.APPLICATION_OCTET_STREAM))现在请求看起来不错,但是Jersey抛出异常:
Now request looks fine, but Jersey throws exception:
INFO: 2 * Sending client request on thread main 2 > PUT 192.168.1.10:8080/v1/AUTH_system/08138784704e2/test 2 > Content-Length: 2760033628 2 > Content-Type: application/octet-stream 2 > X-Auth-Token: AUTH_tka2d071e5ba3e46e58cbbc3bdcc57bc70 Exception in thread "main" javax.ws.rs.ProcessingException: org.apache.http.client.ClientProtocolException at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:472) at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:254) at org.glassfish.jersey.client.JerseyInvocation.lambda$invoke$0(JerseyInvocation.java:729) at org.glassfish.jersey.internal.Errors.process(Errors.java:292) at org.glassfish.jersey.internal.Errors.process(Errors.java:274) at org.glassfish.jersey.internal.Errors.process(Errors.java:205) at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:390) at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:728) at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:421) at org.glassfish.jersey.client.JerseyInvocation$Builder.put(JerseyInvocation.java:310) at copier.Main.main(Main.java:118) Caused by: org.apache.http.client.ClientProtocolException at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:186) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:71) at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:426) ... 10 more Caused by: org.apache.http.ProtocolException: Content-Length header already present at org.apache.http.protocol.RequestContent.process(RequestContent.java:96) at org.apache.http.protocol.ImmutableHttpProcessor.process(ImmutableHttpProcessor.java:132) at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:182) at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88) at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184) ... 12 more如何正确执行?
推荐答案我用Apache HC替换了Jersey,
I replaced Jersey with Apache HC,
Long contentLength = Long.parseLong(sourceResponse.getHeaders(HTTP.CONTENT_LEN)[0].getValue()); HttpPut putRequest = new HttpPut(destinationUrl); putRequest.addHeader(HEADER_X_AUTH_TOKEN, cmd.getOptionValue("dat")); InputStreamEntity entity = new InputStreamEntity(is, contentLength, ContentType.APPLICATION_OCTET_STREAM); putRequest.setEntity(entity);它具有InputStream包装器,可以指定长度.
It has InputStream wrapper with the ability to specify the length.
PS ^另外,Chunked Transfer Encoding在Apache HC中可以正常工作,但是我无法在Jersey Client中将其打开.
PS^ In addition, Chunked Transfer Encoding works correctly in Apache HC, but I could not turn it on in Jersey Client.
更多推荐
泽西岛HTTP客户端:放置具有自定义内容长度的请求
发布评论