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

4

我有一个原始的 inputStream 和一个 HttpServletRequest,我需要使用 JAX-RS 客户端将接收到的整个 inputStream 及其头信息发送到另一个 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>)。输入流可能包含任何原始数据。

1个回答

10

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

对于MediaType(和标头),我建议在您的资源类中注入@Context HttpHeaders,这样更容易查找特定标头。 您可以执行以下操作:

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

在构建请求时,您还可以遍历标头。

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对象的创建成本很高。只要在创建后不更改其配置,您就可以为不同的请求重用相同的 Client

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

System.setProperty("sun.net.http.allowRestrictedHeaders", "true");

但是老实说,我不确定这个警告的意义和任何安全方面的影响,所以你可能需要自己去了解一下。


1
由于我正在使用Grizzly框架,因此无法获得@Context HttpHeaders,因此我注入了Provider <Request> grizzlyRequestProvider以获取所需的标头。感谢您的帮助。 - Manas Pratim Chamuah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接