今回は、Jerseyを使用してXML/JSON形式のレスポンス情報を取得するだけのシンプルなWebアプリケーションを作成します。
また、Webアプリケーションを作成するとき、ビルドスクリプトに記載するライブラリ依存関係の指定誤りなどにより発生した問題内容と解決方法もあわせて紹介していきます。
環境
検証に使用した環境/ライブラリを以下に記載します。
- Windows
- バージョン:10(1909)
- Java
- バージョン:11
- Gradle
- バージョン:6.0
- Jersey
- バージョン:2.31
- Webサーバー
- Tomcat
- バージョン:8.5.49
- Jetty
- バージョン:9.4.24.v20191120
- Tomcat
ビルドスクリプト
検証に使用したビルドスクリプトを次に記載します。
plugins {
id 'java'
id 'org.gretty' version '3.0.3'
}
sourceCompatibility = '11'
targetCompatibility = '11'
compileJava.options.encoding = 'UTF-8'
compileTestJava.options.encoding = 'UTF-8'
repositories {
jcenter()
}
dependencies {
// lombok
implementation 'org.projectlombok:lombok:1.18.12'
annotationProcessor 'org.projectlombok:lombok:1.18.12'
// jersey
implementation 'org.glassfish.jersey.containers:jersey-container-servlet:2.31'
implementation 'org.glassfish.jersey.inject:jersey-hk2:2.31'
// json
implementation 'org.glassfish.jersey.media:jersey-media-json-jackson:2.31'
// xml
implementation 'javax.xml.bind:jaxb-api:2.3.1'
implementation 'org.glassfish.jaxb:jaxb-runtime:2.3.3'
}
サンプルプロジェクト
完成したサンプルWebアプリケーションは、次から取得することができます。
ソースコード
アプリケーションを作成するための処理を作成していきます。
アプリケーションクラス
Jerseyを起動するためのアプリケーションクラスを作成します。
package com.example;
import javax.ws.rs.ApplicationPath;
import org.glassfish.jersey.server.ResourceConfig;
@ApplicationPath("/")
public class Application extends ResourceConfig {
public Application() {
this.packages(this.getClass().getPackage().getName());
}
}
モデルクラス
レスポンス情報として使用するためのモデルクラスを作成します。
package com.example.dto;
import javax.xml.bind.annotation.XmlRootElement;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@XmlRootElement
public class Customer {
private String name;
private int age;
}
リソースクラス
XML形式を返却するリソースクラスを作成します。
package com.example.resources;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.example.dto.Customer;
@Path("/xml")
public class XmlResource {
@GET
@Produces(MediaType.APPLICATION_XML)
public Response json() {
Customer e = new Customer();
e.setName("山田太郎");
e.setAge(20);
return Response.ok(e).build();
}
}
JSON形式を返却するリソースクラスを作成します。
package com.example.resources;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.example.dto.Customer;
@Path("/json")
public class JsonResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response json() {
Customer e = new Customer();
e.setName("山田太郎");
e.setAge(20);
return Response.ok(e).build();
}
}
動作確認
処理の作成が完了したら動作確認を実施していきます。
起動方法
アプリケーションを起動します。起動するServletコンテナは、次の方法で指定して起動することができます。
Tomcatで起動する
Tomcatで起動する場合は、次のコマンドを実行します。
gradlew tomcatRun
Jettyで起動する
Jettyで起動する場合は、次のコマンドを実行します。
gradlew jettyRun
レスポンス確認
起動が完了したら、レスポンス情報を取得できることを確認していきます。
XML形式
次のURLにアクセスすることで、XML形式のレスポンスが取得できることを確認します。
http://localhost:8080/example-simple-jersey/xml
レスポンスとして、次の情報が返却できていることを確認することができます。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customer>
<age>20</age>
<name>山田太郎</name>
</customer>
JSON形式
次のURLにアクセスすることで、JSON形式のレスポンスが取得できることを確認します。
http://localhost:8080/example-simple-jersey/json
レスポンスとして、次の情報が返却できていることを確認することができます。
{"name":"山田太郎","age":20}
問題内容と解決方法
アプリケーション作成時に発生した問題内容と解決方法を紹介していきます。問題が発生した場合は参考にしてみてください。
起動時
アプリケーション起動時に、クラスが存在しないことを示す次の例外が発生することがあります。
java.lang.ClassNotFoundException: javax.xml.bind.JAXBException
【原因:ライブラリが不足している】
Java 11では、JAXB(Java Architecture for XML Binding)が標準ライブラリから削除されています。次に記載するライブラリをビルドスクリプトに追加する必要があります。
implementation 'javax.xml.bind:jaxb-api:2.3.1'
リソースアクセス時(XML形式)
XML形式リソースのアクセス時に、ログに次のような情報が出力されます。
MessageBodyWriter not found for media type=application/xml, type=class com.example.dto.Customer, genericType=class com.example.dto.Customer
この問題が発生する場合は、原因として2つの可能性が考えれます。
【原因1:アノテーションが不足している】
モデルクラスに、次のアノテーションが付与されていない可能性があります。
@XmlRootElement
アノテーションが付与されていない場合は、モデルクラスをXML形式のレスポンスとして扱えないため、このようなエラーが発生する可能性があります。
【原因2:ライブラリが不足している】
XML形式のレスポンスを作成するためのライブラリが不足している可能性があります。次に記載するライブラリをビルドスクリプトに追加する必要があります。
implementation 'org.glassfish.jaxb:jaxb-runtime:2.3.3'
起動時に発生する問題の対策として、ビルドスクリプトにJAXBに関連するライブラリを追加しています。
ただし、追加したライブラリはインタフェースのみを提供するライブラリとなります。実行するためにはインタフェースを実装したクラスが必要になります。
リソースアクセス時(JSON形式)
JSON形式リソースのアクセス時に、ログに次のような情報が出力されます。
MessageBodyWriter not found for media type=application/json, type=class com.example.dto.Customer, genericType=class com.example.dto.Customer
【原因:ライブラリが不足している】
JSON形式を作成するためのライブラリが不足しています。次に記載するライブラリをビルドスクリプトに追加してください。
implementation 'org.glassfish.jersey.media:jersey-media-json-jackson:2.31'
まとめ
Jerseyを使用してXML/SON形式のレスポスを取得するためのサンプルのWebアプリケーションの実装方法と注意事項を紹介しました。