組み込みTomcatのうえでJersey MVCを動かす必要に迫られて調べたのですが参考になるドキュメントをなかなか見つけられずハマったので、得た知見をシェアします!
以下記事で利用しているソースコードはGitHubにあげてあります。
筆者の前提
- Maven 3.0
- JDK 1.8
- Mavenあんまり分かってない
- ミドルウェアほとんど分かってない
JerseyMVCでアプリを書く
JerseyMVCはJavaで簡単にRESTfulなWebアプリが作れるフレームワーク。アノテーションでURLとメソッドを紐付けることができる。
先人の智慧をそのまま参考にさせていただきました。
以下のように、
@Path("hello-mvc")
public class MyResource {
/**
* /hello-mvcへのGETリクエストを受け取ってJSPを返却する。
* @return Viewableインスタンス
*/
@GET
public Viewable helloworld() {
return new Viewable("/hello-mvc");
}
}
アノテーションでPathとHTTPメソッドを指定したコントローラーを書いて、
this.packages(MyApplication.class.getPackage().getName()).register(JspMvcFeature.class);
それをアプリケーションの部品としてJspMvcFeature
に登録して、
<filter>
<filter-name>Jersey MVC JSP Filter</filter-name>
<filter-class>org.glassfish.jersey.servlet.ServletContainer</filter-class>
<init-param>
<!-- MyApplicationクラスをJAX-RSのアプリケーションとして登録 -->
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.example.MyApplication</param-value>
</init-param>
<!-- ... -->
</filter>
web.xml
でそれを読み込むようにfilterの設定を書くと、URLに対応づけられてアプリが動くようになる。
組み込みTomcatの設定
組み込みTomcatを動かすための依存関係をpom.xml
に記述。参考資料参照。
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>8.0.26</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-logging-juli</artifactId>
<version>8.0.26</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>8.0.26</version>
</dependency>
tomcat-embed-core
とtomcat-embed-logging-juli
は必須で、tomcat-embed-jasper
はJSPを扱うために必要なオプションのライブラリ。
これを取り込んでおけば以下のようにTomcatが起動できる。
// Tomcatインスタンスを宣言
Tomcat tomcat = new Tomcat();
tomcat.setPort(9000);
String baseDoc = new File("src/main/webapp").getAbsolutePath(); // DocumentBaseを設定
Context ctx = tomcat.addContext("/servletSample", baseDoc); // ContextPathを設定
tomcat.addWebapp(null, "", baseDoc); // webappにアプリケーションを追加
// 単にサーブレットだけを追加するなら以下のように。
// これでhttp://localhost:8080/servletSample でHelloWorldServletにアクセスできる。
// HelloWorldServlet自体はHttpServletを継承した、ただのServletクラス。
tomcat.addServlet(ctx, "HelloWorld", new HelloWorldServlet());
ctx.addServletMapping("/*", "HelloWorld");
// Tomcatの起動と永続化
tomcat.start();
while (true) {
Thread.sleep(5000);
}
ここでキモなのが、tomcat.addWebapp(null, "", baseDoc)
。Webアプリケーションのフレームワークにお世話になるならこの形式でプロジェクト内のWebアプリをデプロイしてもらう必要がある。
今回の学び
組み込みTomcatとJerseyMVCを同時に使用して思い通りに動作しないとどっちが悪いのかわからないまま全部良くないような気がしてくる。けれど上記の通り、それぞれは単にサーブレットコンテナとWebアプリの関係であるから、分けて考えることができる。
あと使用する技術要素は、時間をかけても1個ずつ基本を押さえておかないと、結局後からハマって余計時間がかかる。
明日のためにClojureの勉強しておこう。