JAX-RS(特にJersey)の自動HTTPコンテンツネゴシエーション、つまり「Accept」や「Content-Type」ヘッダーによってリソースをルーティングする機能を楽しんでいます。しかし、対立がある場合、それでは十分なコントロールが得られない場合があることに気づきました。
たとえば、次のエンドポイントについて考えてみます。
@Path("/order")
public class OrderController {
@GET
@Path("{orderID: \\d+}")
@Produces("text/html")
public View getOrderView(@PathParam("orderID") long id) {
Order order = this.getOrderData(id);
return new OrderView(order);
}
@GET
@Path("{orderID: \\d+}")
@Produces({"application/json", "application/xml"})
public Order getOrderData(@PathParam("orderID") long id) {
return new OrderService.findOrder(id);
}
}
FirefoxとChromeで異なる結果が得られます。FirefoxはHTMLエンドポイントにマップされますが、ChromeはエンドポイントURLにそれぞれ移動するとXMLエンドポイントをトリガーします。それらの違いは、AcceptヘッダーにリストされているMIMEタイプの順序です。Chromeは以下を送信します。
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.107 Safari/534.13
Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Firefoxでは、HTMLが最初にリストされます。
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
すべてが同じように重み付けされている場合、最初のエントリと一致することは論理的であるように思われます。しかし、私の場合、私は私が望むものとは異なる結果を得ているので、タイブレークのためのより良い方法を決定するのは素晴らしいことです。
私の質問:これらのメソッドにヘッダー情報を挿入し、メディアタイプ処理を自分で実行する以外に、同点の場合にいわば「重みを微調整」する方法はありますか?たとえば、常にXMLをHTMLよりも優先するように指示できますか?私のRESTfulクライアントは、どのタイプを返したいかについて非常に明確ですが、ブラウザーはAcceptヘッダーでずさんなことで有名です。(個人的には、HTMLをXMLより少し上に重み付けする必要があると思います。これはユーザーが期待することですが、少し遅れています。)
または、一元化された場所で1回だけ独自のカスタムコンテンツネゴシエーションを実行できますか?私はこのロジックを手動で書き出すことに反対していませんが、それが私のリソースのすべてのインスタンスに適用することを意味する場合はそうではありません。JAX-RSには、ルーティングされる前にリクエストを微調整するためにパイプラインにフィルターを追加するという概念がありますか?