Jersey Dapatkan Header dari Empty Response

Aug 26 2020

Saya mencoba memperbarui bagian dari basis kode lama yang tidak sepenuhnya saya mengerti untuk bekerja dengan versi REST API yang lebih baru. Saya juga tidak memiliki akses ke internal. Saya memiliki contoh Swagger darinya dan dapat memintanya dengan sukses melalui curl, tetapi Jersey berperilaku buruk atau saya salah paham bagaimana membaca sesuatu.

Jika saya menjalankan curlperintah berikut :

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=@[file]" -F "metaData=[other file]"

Saya mendapatkan tanggapan berikut:

> 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

Ini menyiratkan kepada saya bahwa tanggapan POST yang memiliki badan kosong tetapi header tidak kosong adalah valid. Namun, ketika saya mencoba melakukan hal yang sama melalui 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);

Saya mendapat nullrespons meskipun saya tahu dari memeriksa log server bahwa perintah API telah diterima dan diproses dengan sukses.

Setelah waktu yang lama dengan debugger, saya telah menentukan bahwa ini karena Jersey akan mengembalikan objek null atau mengeluarkan pengecualian jika datanya nol. (Lihat di sini untuk konteks lebih lanjut. Meskipun anehnya saya tidak dapat menemukan bagian yang mereka referensikan dalam dokumen spesifikasi mana pun yang dapat saya temukan melalui Google.)

Ini mungkin baik-baik saja karena saya tidak terlalu tertarik dengan isi kosong dari respons, tetapi saya tidak tahu cara mengembalikan header HTTP sebagai hasil dari POST saya di Java.

Jawaban

1 PaulSamsotha Aug 26 2020 at 14:21

Anda tidak bisa mendapatkan header karena Anda menggunakan metode ini untuk hanya meminta isi sebagai respons. Yang Anda inginkan adalah keseluruhan Responseobjek. Untuk mendapatkannya, tinggalkan argumen terakhir (JsonNode.class) ke .post()metode. Metode kelebihan beban yang Anda gunakan mengatakan bahwa Anda tidak peduli tentang apa pun kecuali respons tubuh. Dan itulah yang akan Anda dapatkan.

Saat Anda menggunakan post()metode kelebihan beban tanpa parameter tipe tubuh terakhir, tipe yang dikembalikan adalah Response. Anda bisa mendapatkan header darinya dan isi.

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);