S-JIS[2024-03-10] 変更履歴
JAX-RSのClientクラスのメモ。
JAX-RSでREST APIを呼び出すにはClientインターフェースを使用する。
〜 dependencies { compileOnly 'jakarta.ws.rs:jakarta.ws.rs-api:3.1.0' }
import jakarta.ws.rs.client.Client; import jakarta.ws.rs.client.ClientBuilder; import jakarta.ws.rs.client.WebTarget;
try (Client client = ClientBuilder.newClient()) { WebTarget target = client.target("http://localhost:8080/example/api/resource1"); String result = target.request().get(String.class); System.out.println(result); }
Clientはインターフェースであり、コーディングするだけなら上記で充分だが、実行する際にはその実装が必要となる。
APサーバー(GlassFishやWildFly等)上で実行する場合は自動的に実装が入ってくるが、
単独でクライアントとして実行する場合はクライアントの実装(jersey-clientやRESTEasy等)が必要。
(jersey-clientやRESTEasyをdependenciesに加えれば、jakarta-ws.rs-apiは自動的に入ってくるので明示的にdependenciesに入れる必要は無い)
ClientからWebTargetを取得する際にURI(パス)を指定するが、その方法はいくつかある。
WebTarget target = client.target("http://localhost:8080/example/api/resource1/hello"); WebTarget target = client.target("http://localhost:8080/example/api").path("/resource1/hello"); WebTarget target = client.target("http://localhost:8080/example/api").path("/resource1").path("/hello"); WebTarget target = client.target("http://localhost:8080/example/api").path("resource1").path("hello");
WebTarget target = client.target("http://localhost:8080/example").path("/api").path("/resource1").path("/hello"); WebTarget target = client.target("http://localhost:8080/example").path("api").path("resource1").path("hello");
REST APIでJSONを使う場合、Clientに「JSONのシリアライズ・デシリアライズを行うクラス」が入っている必要がある。
APサーバー(GlassFishやWildFly等)上で実行する場合は自動的に入ってくるようなので、自分で何かする必要は無い。
単独でクライアントとして使用する場合は、ClientにJacksonJsonProviderを登録してやる必要がある。
(もしかしたら、クライアントの実装によっては不要かもしれないが)
〜 dependencies { 〜 implementation 'com.fasterxml.jackson.jakarta.rs:jackson-jakarta-rs-json-provider:2.16.1' }
import com.fasterxml.jackson.jakarta.rs.json.JacksonJsonProvider; import jakarta.ws.rs.client.ClientBuilder;
try (var client = ClientBuilder.newClient()) { client.register(JacksonJsonProvider.class); 〜 }
import com.fasterxml.jackson.jakarta.rs.json.JacksonJsonProvider; import jakarta.ws.rs.client.ClientBuilder;
try (var client = ClientBuilder.newBuilder().register(JacksonJsonProvider.class).build()) { 〜 }
サーバーからJSONを返す例で返ってきたJSONをJavaBeansとして受け取る例。
(ClientにJacksonJsonProviderが登録されている必要がある)
import jakarta.ws.rs.client.Client; import jakarta.ws.rs.client.WebTarget;
// 受け取るJavaBeans public class MyResultBean { private String name; private List<String> valueList; 〜setter/getter/toString〜 }
static void returnJson(Client client) { WebTarget target = client.target("http://localhost:8080/example/api").path("/resource1/return-json"); MyResultBean result = target.request().get(MyResultBean.class); System.out.println(result); }
なお、HTTPレスポンスがOKでない場合はJSONでないメッセージ(MyResultBeanに変換できないメッセージ)が返ってきているかもしれないので、エラーチェックはした方がいい。
→HTTPレスポンスを確認する例
サーバー側がJSONを受け取るようになっているとき、そこにJSONを送信する例。
(ClientにJacksonJsonProviderが登録されている必要がある)
public class MyRequestBean { private String name; private String value; 〜setter/getter〜 }
import jakarta.ws.rs.client.Client; import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.client.WebTarget; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response;
static void jsonParameter(Client client) { var request = new MyRequestBean(); request.setName("test-user"); request.setValue("test-value"); WebTarget target = client.target("http://localhost:8080/example/api").path("/resource1/json-parameter"); Response response = target.request().post(Entity.entity(request, MediaType.APPLICATION_JSON)); String result = response.readEntity(String.class); System.out.println(result); }
HTTPリクエストのPOSTメソッドの場合は、request()のpostメソッドを使う。
postメソッドはgetメソッドと違って結果クラスで直接受け取る方法が無いようなので、一旦Responseで受け取り、readEntityメソッドで結果を取得する。
サーバー側でJSONを送受信するようになっているとき、そこにJSONを送受信する例。
JSONを送信する例とJSONを受け取る例を融合するだけ。
import jakarta.ws.rs.client.Client; import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.client.WebTarget; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response;
static void helloJson(Client client) { var request = new MyRequestBean(); request.setName("test-user"); request.setValue("test-value"); WebTarget target = client.target("http://localhost:8080/example/api").path("/resource1/hello-json"); Response response = target.request().post(Entity.entity(request, MediaType.APPLICATION_JSON)); if (response.getStatus() == Response.Status.OK.getStatusCode()) { MyResultBean result = response.readEntity(MyResultBean.class); System.out.println(result); } else { System.out.println(response.getStatus()); // HTTPレスポンスのステータスの数値 var status = Response.Status.fromStatusCode(response.getStatus()); System.out.println(status.toString()); // reason phrase String result = response.readEntity(String.class); System.out.println(result); } }