Jersey Get Headers from Empty Response

huangapple go评论123阅读模式
英文:

Jersey Get Headers from Empty Response

问题

ClientConfig config = new ClientConfig();
config.register(MultiPartFeature.class);
Client client = ClientBuilder.newClient(config);
WebTarget endpoint = client.target([uri]);
FormDataMultiPart post = new FormDataMultiPart()
    .field("sender", [email], MediaType.TEXT_PLAIN_TYPE)
    .field("recipient", [email], MediaType.TEXT_PLAIN_TYPE)
    .field("fileType", "file", MediaType.TEXT_PLAIN_TYPE)
    .field("data", [InputStream], MediaType.APPLICATION_OCTET_STREAM_TYPE)
    .field("metaData", [other InputStream], MediaType.APPLICATION_OCTET_STREAM_TYPE);
JsonNode response = endpoint.path([api path])
    .request(MediaType.APPLICATION_JSON)
    .header("Authorization", "Bearer " + [jwtTokenString])
    .post(Entity.entity(post, MediaType.MULTIPART_FORM_DATA_TYPE), JsonNode.class);

Please note that I'm providing the translated Java code based on your request. If you need further assistance or have any questions, feel free to ask.

英文:

I'm trying to update part of a legacy codebase I don't fully understand to work with a newer version of a REST API I also don't have access to the internals of. I do have a Swagger instance of it and can invoke it successfully via curl, but either Jersey is misbehaving or I'm misunderstanding how to read something.

If I execute the following curl command:

curl -v -k -X POST "[api endpoint]" -H  "accept: application/json" -H  "Authorization: Bearer [jwt token]" -H  "Content-Type: multipart/form-data" -F "sender=[email address]" -F "recipient=[email address]" -F "fileType=file" -F "data=@" -F "metaData=[other file]"

I get the following response:

> Content-Length: [#]
> Content-Type: multipart/form-data; boundary=------------------------9b1405ed70c2fd40
>
} [5 bytes data]
* We are completely uploaded and fine
{ [5 bytes data]
* Mark bundle as not supporting multiuse
< HTTP/1.1 201 Created
< Date: Wed, 26 Aug 2020 00:29:56 GMT
< Cache-Control: no-cache, no-store, must-revalidate
< Pragma: no-cache
< Expires: Thu, 01 Jan 1970 00:00:00 GMT
< Set-Cookie: JSESSIONID=[ID];Path=/;Secure
< Keep-Alive: timeout=600
< X-Frame-Options: SAMEORIGIN
< Server: WildFly
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, POST, DELETE, PUT
< Connection: Keep-Alive
< Access-Control-Allow-Headers: Content-Type
< Content-Type: application/json
< Location: [value I care about]
< Content-Length: 0
<
100  1667    0     0  100  1667      0   1825 --:--:-- --:--:-- --:--:--  1825
* Connection #0 to host [proxy] left intact

This implies to me that POST responses which have empty bodies but nonempty headers are valid. However, when I try to effect the same thing via Jersey:

ClientConfig config = new ClientConfig();
config.register(MultiPartFeature.class);
Client client = ClientBuilder.newClient(config);
WebTarget endpoint = client.target([uri]);
FormDataMultiPart post = new FormDataMultiPart()
	.field("sender", [email], MediaType.TEXT_PLAIN_TYPE)
	.field("recipient", [email], MediaType.TEXT_PLAIN_TYPE)
	.field("fileType", "file", MediaType.TEXT_PLAIN_TYPE)
	.field("data", [InputStream], MediaType.APPLICATION_OCTET_STREAM_TYPE)
	.field("metaData", [other InputStream], MediaType.APPLICATION_OCTET_STREAM_TYPE);
JsonNode response = endpoint.path([api path])
	.request(MediaType.APPLICATION_JSON)
	.header("Authorization", "Bearer " + [jwtTokenString])
	.post(Entity.entity(post, MediaType.MULTIPART_FORM_DATA_TYPE), JsonNode.class);

I get a null response even though I know from inspecting server logs that the API command was received and processed successfully.

After a long time with the debugger I've determined that this is because Jersey will either return a null object or throw an exception if the data is null. (See here for more context. Though oddly enough I can't find the section they reference in any of the specification documents I can turn up via Google.)

This is probably fine as I'm not really interested in the empty body of the response, but I can't figure out how to get the HTTP headers returned as a result of my POST in Java.

答案1

得分: 1

你无法获取标头,因为你正在使用仅请求响应主体的方法。你想要的是整个 Response 对象。要做到这一点,省略掉 .post() 方法的最后一个参数 (JsonNode.class)。你正在使用的那个重载方法表明你只关心响应主体。而这也正是你将会得到的。

当你使用不带最后一个主体类型参数的重载 post() 方法时,返回类型将为 Response。你可以从中获取标头和主体。

Response response = endpoint.path([API路径])
    .request(MediaType.APPLICATION_JSON)
    .header("Authorization", "Bearer " + [jwtToken字符串])
    .post(Entity.entity(post, MediaType.MULTIPART_FORM_DATA_TYPE));
URI locationUri = response.getLocation();
String locationHeader = response.getHeaderString("Location");
String body = response.readEntity(String.class);
英文:

You can't get the headers because you are using the method to only ask for the body as the response. What you want is the entire Response object. To get that, leave out the last argument (JsonNode.class) to the .post() method. That overloaded method you're using says that you don't care about anything but the body of the response. And that's what you will get.

When you use the overloaded post() method without the last body type parameter, the return type will be Response. You can get headers from it and the body.

Response response = endpoint.path([api path])
    .request(MediaType.APPLICATION_JSON)
    .header("Authorization", "Bearer " + [jwtTokenString])
    .post(Entity.entity(post, MediaType.MULTIPART_FORM_DATA_TYPE));
URI locationUri = response.getLocation();
String locationHeader = response.getHeaderString("Location");
String body = response.readEntity(String.class);

huangapple
  • 本文由 发表于 2020年8月26日 08:58:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/63589047.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定