NonRepeatableRequestException using jersey and apa

2019-07-12 18:53发布

问题:

I try to upload a file via REST using Jersey (Moxy). For NTLM authentication I use the Apache HttpClient Lib and the Jersey Apache Connector.

CredentialsProvider credProvider = new BasicCredentialsProvider();

credProvider.setCredentials(new AuthScope(host,
    port, AuthScope.ANY_REALM),
    new NTCredentials(user, pass, host, domain));

clientConfig.property(ApacheClientProperties.CREDENTIALS_PROVIDER,
    credProvider);
clientConfig.connectorProvider(new ApacheConnectorProvider());

client = ClientBuilder
    .newClient(clientConfig)
    .register(MultiPartFeature.class)
    .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);

The byte array with the file content should be sent with a POST request in the request body (no multipart request / no other data).

When I use a REST resource which handles a simple POST request with an empty body everything works fine. But when I try to send the file I get the following error:

javax.ws.rs.ProcessingException: org.apache.http.client.ClientProtocolException
    at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:492)
    at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:245)
[...]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.apache.http.client.ClientProtocolException
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:188)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:72)
    at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:446)
    ... 34 more
Caused by: org.apache.http.client.NonRepeatableRequestException: Cannot retry request with a non-repeatable request entity.
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:207)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:194)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:85)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:186)
    ... 36 more

I tried to send another entity like a JAXB handled object for raising another exception. But the same exception occurs. Without jersey, I implemented a working request.

ByteArrayInputStream buffer = new ByteArrayInputStream(fileContent);
InputStreamEntity i = new InputStreamEntity(buffer, buffer.available());
BufferedHttpEntity entity = new BufferedHttpEntity(i);
HttpPost request = new HttpPost(new URI(targetUrl));
request.setEntity(entity);
//define some request headers here
client.execute(request);

But I like to use jersey to handle the response content easily. How do I send a working POST request with file data as content?