JAX-RSをやってみる (2) - glassfish deployment -
参考: https://jersey.java.net/documentation/latest/deployment.html#deployment.servlet.3
JAX-RSに準拠しているアプリケーションサーバー(glassfish等)ではデプロイ時の設定が若干異なる模様。またJAX-RSに準拠しているアプリケーションサーバーであれば特にデプロイメントデスクリプタ(web.xml)を定義しなくても@ApplicationPathを使う事で引数に指定したパスを<servlet-mapping>のベースとして利用できるようになるっぽい。微妙にややこしいけど
※記述している内容が正しいかは微妙なのであくまで個人的なメモとして
glassfishの環境構築
glassfishのオープンソース版をダウンロードしてきてインストールする。でglassfishはTomcat等とは違い?ドメインっていう形でアプリケーションをデプロイする。で初期状態でもドメインが存在するのだけど、適当に別なドメインを作るので
/path/to/glassfish/bin/asadmin create-domain --profile developer --adminport 14848 --instanceport 10080 devDomain
な感じでWebアプリケーション側のポートを10080で、(Web)管理コンソールのポートを14848でdevDomainっていう名前で作成みたいな感じで。あとは
/path/to/glassfish/bin/startserv devDomain
あたりをやって作ったドメインなサーバーを起動する。でglassfishではアプリケーションをデプロイするには/path/to/glassfish/domains/ドメイン名/autodeployにwarファイルなり打ち込めばデプロイしてくれる模様なので
とりあえずはglassfishな環境構築はこんなもんで
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<!--
<servlet>
<servlet-name>sample.SampleApplication</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>sample.SampleApplication</servlet-name>
<url-pattern>/resources/*</url-pattern>
</servlet-mapping>
-->
</web-app>
@ApplicationPathを使ってJAX-RSアプリケーションなリソースパスをマッピングするので特に記述する必要性は無いけど、もし上記のようにweb.xmlで指定する場合には<servlet-name>にApplicationクラス(又はResourceConfig?)を指定すれば良い(<serlet-class>は必要ないっぽい)。又、特にApplicationクラスを拡張しないで使うようなケースであれば、javax.ws.rs.core.Applicationを指定すれば良い模様
SampleApplication.java
package sample;
import javax.ws.rs.ApplicationPath;
import org.glassfish.jersey.server.ResourceConfig;
@ApplicationPath("resources")
public class SampleApplication extends ResourceConfig {
public SampleApplication() {
packages("sample");
}
}
っていう感じで@ApplicationPathでresourcesを引数で指定すると、その指定された引数がベースなリソースパスになる模様なので http://localhost:10080/context_name/resource_path/@Path 等で指定されているメソッドなりのハンドラ的な感じで実行できる
っていうわけで上記なプロジェクトをコンパイル後warにパッケージングして
mv jaxrs.war /path/to/glassfish/domains/devDomain/autodeploy
にぶん投げる。で@ApplicationPathで指定したリソースパスでアクセス出来るかを確認してみりゃ良い。
余談: glassfishでJSONをレンダリングするにあたって
※GlassFish4だと問題が発生しない模様
JSONとしてレンダリングする場合であってもオブジェクトに@XmlRootElementが無い場合とかだとWebApplicationExceptionが発生する模様。又、アクション側において
package sample.controller;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import sample.bean.SampleBean;
import static javax.ws.rs.core.MediaType.*;
@Path("/sample")
public class Home {
@Path("list")
@GET
@Produces(APPLICATION_JSON)
public List<SampleBean> list() {
List<SampleBean> beans = new ArrayList<SampleBean>(2);
beans.add(new SampleBean("hoge/fuga"));
beans.add(new SampleBean("foobar"));
return beans;
}
}
のようにした場合のJSONレスポンスは
っていうようにjava.util.Listで出してもオブジェクト形式なレスポンスが送出される模様。こういう場合にちゃんと配列なJSONレスポンスを返す場合にはListなジェネリクスをObjectに指定すれば良い模様