Jerseyで@Pathとurl-patternの設定でハマった
拡張子の付いたファイルのURL(例えば「http://example.com/api.json」)へのレスポンスをJerseyで受け付けようとして、設定でハマったのでメモしておく。
1.リクエストURLとweb.xmlのurl-patternと@Pathの対応について
リクエストが受け付けられる場合はOK、404 Not FoundとなるものはNGとする。
リクエストURL url-pattern @Path OK/NG ------------------------------------+------------+-----------------------+----- http://example.com/api/lookup /api/* @Path("/lookup") OK http://example.com/api/lookup.json /api/* @Path("/lookup.json") OK http://example.com/lookup.json *.json @Path("/lookup.json") NG http://example.com/lookup.json *.json @Path("/") OK http://example.com/lookup.json/hoge *.json @Path("/hoge") NG
url-pattern
が「/api/*」といった前方一致の記述方法の場合は納得できるのだが、「*.json」といった拡張子の記述方法の場合は妙な対応付けになってしまう(特に3行目がNGというのが、直観に反していていただけない)。ということで、Jerseyへマッピングする際は、url-patternに拡張子マッチングの記述方法は使用しないことにする。
2.Jerseyのデバッグについて
web.xmlを以下のようにすると、レスポンスヘッダーに「X-Jersey-Tracing-XXX」の形式でトレースログが出力されるようになる。上記のようにマッピング回りで悩んだ場合は設定して動作検証を行う。
<servlet> <servlet-name>jersey-api</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.api</param-value> </init-param> <init-param> <param-name>jersey.config.server.tracing.type</param-name> <param-value>ALL</param-value> </init-param> <init-param> <param-name>jersey.config.server.tracing.threshold</param-name> <param-value>VERBOSE</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
3.その他のURL変換機構
蛇足。
先日書いた「ルートURLへのリクエストをJerseyで受け付ける」では、「http://example.com/」へのアクセスがwelcome-file
の設定によりhttp://example.com/index.do
へのリクエストへ変換され、url-pattern
「*.do」、@Path
「@Path(“/”)」に一致する流れを書いた。このように、URLの変換は様々な箇所で行われている。
例えば、今扱っているサイトで使っている、Apache2とTomcat7との連携用モジュールmod_proxy_ajpもURLを変換する設定が記述できるし、Apache2のURL書き換えモジュールmod_rewriteでも変換が行える。さらに言えば、企業のWEBサイトなどではhttpサーバの前段に配置されるBIG-IP等負荷分散装置にてURLの書き換えが行われる場合もある。他にもまだあるかもしれないが、、とにかくブラウザで指定されたURLが実際のプログラムへマッピングされるまでの間には何回もURL変換がされているということだ。。