はじめに
RESTful API を実装しようと思い、調べましたが、古い情報が多かったので
少し新しい情報として書き留めておきます。
目的
- RESTful APIの開発環境を簡単に構築したい
- 開発ツールは Eclipse を使う
- JAX-RSの仕様の実装として Jersey を使う
- WEBサーバーは Tomcat を使う
J2EE のサーバーである必要は無く、Spring等のフレームワークも使いません。
とりあえずプロジェクトのテンプレートとして使える事を目的にしています。
Eclipse で Jersey を使う
RESTful をサービスを提供する為に Java EE では JAX-RS という仕様があります。
その実装には Apache CXF 等いくつかありますが、その中で Jersey(GlassFish版) を使うことにしました。
使用例が多く、バージョンの更新も活発に行われているのが理由です。
Eclipseは Pleiades を使います。
作成するプロジェクトの概要
実行するとブラウザが立ち上がり以下の様なWEBページが表示されます。

リンクをクリックして「Got it!」が表示されれば環境構築が正常に出来ていることが確認できます。

後は、サンプルプログラムを消して、自分のプログラムを書いていけば良いと思います。
プロジェクトの作成
では、手順を解説していきます。
maven の jersey-quickstart-webapp アーティファクトを使います。
これは、Jersey の環境と簡単なサンプルを内包しています。
まずプロジェクトを新規で作ります。
ここでは「mavenプロジェクト」で作成します。
その中で、アーキタイプを選択します。アーキタイプはプロジェクトの雛型です。
沢山表示されるので、フィルターで、「glassfish.jersey」と入力すれば絞れます。

「jersey-quickstart-webapp」を選択します。
最新バージョンしか表示されていませんが、チェックを外すと過去のバージョンも選択できます。
後で詳しく述べますが、バージョンの選択は重要です。
少なくとも、ここで選択したのは Tomcat10 以上を使う前提です。
入力画面に進みます。

入力項目 | 対応するEclipseの項目 |
---|---|
グループId | パッケージ名 |
アーティファクトId | プロジェクト名 |
という関係です。
名前は何でも良いですが、アーティファクトId は、Eclipse のプロジェクト名にもなるので、それを踏まえて付けて下さい。
「完了」でプロジェクトが作成されます。
※最後に、コンソールに「Y」を入力するのを忘れずに
実行してみる
「サーバーで実行」を選択し、Eclipseにインストール済の Tomcat を選択します。
ここでは Tomcat10 以上を選択します。

Jersey3.x以上は Tomcat9 以下では動きません。
プロジェクトの概要で説明した画面が表示されれば完了です。
追加で設定しておきたい事
- Servlet3.0 以上に設定する
- Applicationサブクラスを追加する
- JSON を有効にする
Servlet3.0 以上にする
pom.xml 中のコメントの記載通りに、既存の Artifact の記述を削除して、代わりにコメントを外して有効にしましょう。
<!-- artifactId>jersey-container-servlet-core</artifactId -->
<!-- use the following artifactId if you don't need servlet 2.x compatibility -->
<artifactId>jersey-container-servlet</artifactId>
今時、servlet2.x を使う事などあり得ません。
また、これを行わないと、Applicationサブクラス が働きません。
Applicationサブクラスを追加
補足ですが、JAX-RSの仕様では
- Applicationサブクラス
- リソースクラス
の2つがあり、Applicationサブクラスがあれば web.xml は必要ありません。
Applicationサブクラスは@ApplicationPathアノテーションを使って基底の URI を決める事が出来ます。
例えば、MyApplication.java を src/main/java 配下のどこかに作成します。
@ApplicationPath("/webapi")
public class MyApplication extends Application {
public Set<Class<?>> getClasses() {
Set<Class<?>> s = new HashSet<Class<?>>();
s.add(MyResource.class); // 作成したリソースクラス
return s;
}
}
もしくは Jersey 限定で良ければ、もう少し簡単に書けます。
@ApplicationPath("/webapi")
public class MyApplication extends ResourceConfig {
public MyApplication() {
packages("MyPackage"); // 作成したパッケージ名
}
}
多くの解説では作成したら不要だから web.xml は削除しろと書いてある場合が多いですが、Servlet3.0 用に構築 しないと動きません。
web.xml を削除して、同様に動くか確認しましょう。
なお、web.xml とApplicationサブクラスを併用する事もできます。URI が重複しなければ問題ありません。
JSON を有効にする
現在主流の RESTful API では、受け渡しの形式が JSON です。
デフォルトは、jettison が使われる設定ですが、jackson を使うのが一般的です。
maven で追加しましょう。
<!-- uncomment this to get JSON support
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
</dependency>
-->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</dependency>
<!-- kackson or jettison use regist -->
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-json-jackson -->
従来は、さらに regist しないと有効になりませんでしたが、現状は自動でロードされるようです。
念のために記載しておきます。
public class MyApplication extends ResourceConfig {
public MyApplication() {
packages("app.hoge"); // リソースクラスを含むパッケージ名
register(JacksonFeature.class); // Jackson を有効にする
}
}
サンプルソースを書き換えてテストします。
@GET
@Produces(MediaType.APPLICATION_JSON) // ("application/json")でも同じ
public HashMap<String,String> getIt() {
HashMap<String, String> map = new HashMap<>();
map.put("Got","it!");
return map;
}
Java のクラスを解釈して変換してくれるので楽です。
以上で終わりですが、以降は、うまく動かなかった場合の対処を書いておきます。
トラブルシューティング
最初は、いろいろトラブルが生じたので、記載しておきます。
- Eclipse のコンパイルエラー
- Tomcat のバージョンとの関係
- Tomcat9 で動かしたい場合
Eclipse のコンパイルエラー
下が実際のエラーの例
多くは、「コンソール」窓(ビュー)の横にある「問題」(もしくは「マーカー」と表示)のエラーの説明で解る事が多いです。
- プロジェクトに✖印が付いて他にエラー箇所が無い
- JSPに✖が付いている
- web.xmlに✖が付いている
プロジェクトだけに✖印が付いている場合
プロジェクトを一度「クリーン」してみる。
「Java プロジェクト・ファセットのバージョンと一致しません。」のようなエラーなら、ターゲットとなる Tomcatの実行環境の Java のバージョンがコンパイルの Java のバージョンと一致していない。
プロジェクトの設定で同じにする必要があります。
JSPに✖もしくは web.xmlの✖が付いている場合
Eclipse の検証機能が正しく働いていない可能性があります。
古い Eclipse を使っていたら最新版にしてみるのが良いです。(実際、2021版を2024年版にしたらエラーが消えた)
これらのエラーは無視しても実行できますが、気になるなら、Eclipse の「設定」「検証」で「JSP構文バリデターのビルド」を外す事で対処できるようです。
Tomcat のバージョンとの関係
Tomcat10 以上が無い場合(Eclipseのバージョンが古い)は追加で Tomcat をインストールする事も出来ます。
その際 JREは次の表に従って下さい。
ここにあるように、Java11 以上で動かす必要があります。
ただ、Tomcat10 を Java11 で動かすと下記の問題が見られました。
JSPの画面は表示されるが、リンクをクリックすると、
重大: Web アプリケーション [/jersey40] のサーブレット [Jersey Web Application] の load() メソッドは例外を投げました。 [土 8月 10 18:04:20 JST 2024]
Tomcat10 を Java17 以上で動かすと問題ありませんでした。
Jersey4.0 以上では、Tomcat10 は Java17 以上で動かすのが無難です。
Tomcat9 で動かしたい場合
どうしても、実環境が Tomcat9 しか用意出来ない場合、Jersey のバージョンは 2.x で動かすことになります。
この場合、最初のプロジェクトの新規作成で、アーティファクトは古いバージョンを選ぶ必要があります。
例えば、jersey 2.5 を選びます。
この場合もプロジェクトが正常にビルドできない場合があります。
pom.xml でエラーになる場合
中で記述されている Maven のバージョンが原因です。動くバージョンに書き換える必要があります。例えば、
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.4.0</version>
</plugin>
Tomcat9で実行時にエラーが出る場合
Tomcat9 を Java11 以上で動かしていると起こります。
理由は JAXBException というライブラリが標準ライブラリから除外されたためのようで、
pom.xml で追加するか、Tomcat9 を Java8 で動かすかのどちらかで対処できます。
前者でこのサンプルは動きますが、別のエラーがログに出ているので後者のほうが確実です。
MyResource.java でコンパイルエラーが出る場合
import jakarta.ws.rs.Get のように jakarta が使われるのは Tomcat10 以上を前提にしています。
Tomcat9 では javax.wa.rs.Get のように書き換えます。
Tomcat10 から J2EE 関係は jakarta に変更されている為です。
もともと Tomcat は J2EEサーバーではありませんが、Jersey は J2EE の一部の API を使っているのでこの変更が影響します。
まとめ
トラブルを避ける為に Eclipse はなるべく最新版を使いましょう。
Jersey3.x 以上を使いたければ、Tomcat10 以上を使う必要があります。
案外、落とし穴がありますので、Jersey の基本的な設定を覚えておくと以降の開発が楽になります。