【Jersey】シンプルなWebアプリケーション作成方法の紹介

今回は、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

ビルドスクリプト

検証に使用したビルドスクリプトを次に記載します。

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アプリケーションは、次から取得することができます。

GitHub - fumidzuki/example-simple-jersey
Contribute to fumidzuki/example-simple-jersey development by creating an account on GitHub.

ソースコード

アプリケーションを作成するための処理を作成していきます。

アプリケーションクラス

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つの可能性が考えれます。

【原因:アノテーションが不足している】

モデルクラスに、次のアノテーションが付与されていない可能性があります。

@XmlRootElement

アノテーションが付与されていない場合は、モデルクラスをXML形式のレスポンスとして扱えないため、このようなエラーが発生する可能性があります。

【原因:ライブラリが不足している】

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アプリケーションの実装方法と注意事項を紹介しました。