JAX-RSをやってみる (2) - glassfish deployment -

2014-06-08T00:00:00+00:00 Java JAX-RS

参考: 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に指定すれば良い模様

JAX-RSをやってみる (3) - AutoDiscoverable - JAX-RSをやってみる (1)