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メソッドを使う。