如何使用 JAX-RS 2.0 客户端 API post 原始数据

How to post raw data using JAX-RS 2.0 client API

我有一个原始 inputStream 和一个 HttpServletRequest 我需要使用 [=21 将收到的整个输入流以及 headers 发送到另一个 servlet =] 客户.

Client client = ClientBuilder.newClient();

WebTarget reTarget = client.target("http://localhost:8100/Server");
Invocation retargetInvocation = reTarget.request().??
Response.Response response = retargetInvocation.invoke();

我应该如何为 post 请求 Invocation retargetInvocation = reTarget.request().post(Entity<T>) 进行调用。inputStream 可能包含任何原始数据

使用Entity.entity(inputStream, MediaType.YOUR_MEDIA_TYPE_TYPE)

对于 MediaType(和 headers),我会将 @Context HttpHeaders 注入到您的资源 class 中。它使查找特定 headers 变得更容易。你可以做

Entity.entity(inputStream, httpHeaders.getMediaType());

您还可以在构建请求时遍历 headers

Invocation.Builder builder = client.target(url).request();
for (String header: headers.getRequestHeaders().keySet()) {
    builder.header(header, headers.getHeaderString(header));
}
Response response = builder.post(Entity.entity(is, headers.getMediaType()));

总的来说,它可能看起来像

@Context HttpHeaders headers;

@POST
public Response doForward(InputStream is) {
    Client client = ClientBuilder.newClient();
    String url = "http://localhost:8080/...";
    Invocation.Builder builder = client.target(url).request();
    for (String header: headers.getRequestHeaders().keySet()) {
        builder.header(header, headers.getHeaderString(header));
    }
    Response response = builder.post(Entity.entity(is, headers.getMediaType()));
    return Response.ok(response.getEntity()).build();
}

请记住,Client 的创建成本很高 object。您可以为不同的请求重复使用相同的 Client,只要您在创建后不弄乱它的配置即可。

如果您像我上面那样遍历所有 headers,您将在日志中收到关于允许受限 headers 的警告。您可以使用系统 属性

禁用警告
System.setProperty("sun.net.http.allowRestrictedHeaders", "true");

但老实说,我不确定警告的用途以及任何安全隐患,因此您可以查看一下。