K4750.NET

ルートURLへのリクエストをJerseyで受け付ける

アプリケーションのルートURL(例えば「http://app.k4750.net/nendoroid/」)へのリクエストをJAX-RSの実装であるJerseyで受け付けようとして手間取ったのでメモを残しておく。


1.使用しているアプリケーションコンテナ、ライブラリ等

  • Tomcat 7.0.52
  • Jersey 2.12
  • Thymeleaf 2.1.3 (今回の話題には無関係)

2.web.xml

以下のweb.xmlを持つWebアプリケーションを「http://app.k4750.net/nendoroid/」へデプロイする。

  <servlet>
    <servlet-name>jersey</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>jersey.config.server.provider.packages</param-name>
      <param-value>net.k4750.app.nendoroid</param-value>
    </init-param> 
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>jersey</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>

  <welcome-file-list>
    <welcome-file>index.do</welcome-file>
  </welcome-file-list>

welcome-fileの設定により「http://app.k4750.net/nendoroid/」へのアクセスは「http://app.k4750.net/nendoroid/index.do」へのアクセスとみなされ、url-patternの「*.do」に一致し、JerseyのServletContainerが実行される。因みに、url-patternを「/*」にしてしまうという乱暴なやり方もできなくはないが、Webアプリケーションに含まれる画像(*.jpg等)やJavaScript(*.js)等へのアクセスもすべてServletContainer呼び出しになってしまうため、現実的ではない。


3.アプリケーション

リクエストを受け付けるアプリケーションは以下のとおり。

package net.k4750.app.nendoroid;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

@Path("/")
public class Index {
  @GET
  @Produces("text/html")
  public String exec() {
    return "..."; // HTMLをStringで返す。
  }
}

@PathにリクエストがあったURLの相対パスを記述するのだが、直観に反して(?)@Path("/index.do")ではない。web.xmlのwelcome-fileの設定が適用される前のパス@Path("/")を記述しなければならない。Webアプリケーションの仕様や挙動を熟知していれば当然のことなのかもしれないが、、なんともしっくり来ない動作だと感じる。もっとスマートなやり方はないのだろうかと思う。