Jerseyのjersey-clientのメモ。
jersey-clientはRESTfulなウェブサービスにアクセスするクライアントを作るためのライブラリー。
plugins { id 'java' } java { toolchain { languageVersion = JavaLanguageVersion.of(21) } } tasks.withType(JavaCompile) { options.encoding = 'UTF-8' } repositories { mavenCentral() } dependencies { implementation 'org.glassfish.jersey.core:jersey-client:3.1.5' }
import jakarta.ws.rs.client.Client; import jakarta.ws.rs.client.ClientBuilder; import jakarta.ws.rs.client.WebTarget;
public class RestClientMain { public static void main(String... args) { try (Client client = ClientBuilder.newClient()) { WebTarget target = client.target("http://localhost:8080/base/api/resource1"); // WebTarget target = client.target("http://localhost:8080/base").path("/api").path("/resource1"); // WebTarget target = client.target("http://localhost:8080/base").path("api").path("resource1"); String result = target.request().get(String.class); System.out.println(result); } } }
HTTPリクエストのGETの場合、request()のgetメソッドを呼ぶ。
getメソッドの引数には、取得したいデータ型(クラス)を渡す。
request.get()(引数なし)だとResponseが返る。
この場合はステータス等も取れる。
import jakarta.ws.rs.core.Response;
Response response = target.request().get(); System.out.println(response.getStatus()); String result = response.readEntity(String.class); System.out.println(result);
target.request()はjakarta.ws.rs.client.Invocation.Builderを返すが、このオブジェクトは使い回しが出来るようだ。
ただしスレッドセーフかどうかは不明。
WebTarget target = client.target("http://localhost:8080/base/api/resource1"); var builder = target.request(); String result1 = builder.get(String.class); String result2 = builder.get(String.class);
jersey-serverのJSONを返す例で返ってきたJSONをJavaBeansとして受け取る例。
// 受け取るJavaBeans public class MyResultBean { private String name; private List<String> valueList; 〜setter/getter/toString〜 }
単純な方法としては、JSONを一旦Stringで受け取って、JavaBeansに変換する。
dependencies { implementation 'org.glassfish.jersey.core:jersey-client:3.1.5' implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.3' }
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper;
static void client2_1(Client client) throws JsonMappingException, JsonProcessingException { WebTarget target = client.target("http://localhost:8080/base/api/resource2"); String result = target.request().get(String.class); var objectMapper = new ObjectMapper(); MyResultBean resultBean = objectMapper.readValue(result, MyResultBean.class); System.out.println(resultBean); }
別の方法として、Clientに変換クラス(JacksonJsonProvider)を登録しておく。
dependencies { implementation 'org.glassfish.jersey.core:jersey-client:3.1.5' implementation 'com.fasterxml.jackson.jakarta.rs:jackson-jakarta-rs-json-provider:2.16.1' }
import com.fasterxml.jackson.jakarta.rs.json.JacksonJsonProvider;
static void client2_2(Client client) { client.register(JacksonJsonProvider.class); WebTarget target = client.target("http://localhost:8080/base/api/resource2"); MyResultBean result = target.request().get(MyResultBean.class); System.out.println(result); }
JacksonJsonProviderに関しては、Client生成時にClientBuilderで指定しておくことも出来る。
try (Client client = ClientBuilder.newBuilder().register(JacksonJsonProvider.class).build()) { 〜 }
JacksonJsonProviderがClientに登録されていない場合、以下のような例外が発生する。
Exception in thread "main" org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=application/json, type=class com.example.jersey.client.MyResultBean, genericType=class com.example.jersey.client.MyResultBean.
Responseを経由して取得したい場合は以下のようにする。
WebTarget target = client.target("http://localhost:8080/base/api/resource2"); Response response = target.request().get(); MyResultBean result = response.readEntity(MyResultBean.class); System.out.println(result); }
サーバー側がJSONを受け取るようになっているとき、そこにJSONを送信する例。
(JacksonJsonProviderがClientに登録されている必要がある)
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;
var request = new MyRequestBean(); request.setName("test-user"); request.setValue("test-value"); WebTarget target = client.target("http://localhost:8080/base/api/resource4"); Response response = target.request().post(Entity.entity(request, MediaType.APPLICATION_JSON)); System.out.println(response.readEntity(String.class));
HTTPリクエストのPOSTの場合は、request()のpostメソッドを使う。