読者です 読者をやめる 読者になる 読者になる

Java EE 事始め!

主にJava EEについて、つらつらとマイペースに書いていきます。「Java EEを勉強するときに、一番最初に読んでもらえるブログ」を目指して頑張ります!

JSR 371(MVC 1.0) Early Draft version 1.0 の日本語訳(後編)

この記事について

Java EE 8の新機能であるMVC 1.0のJSR 371 Early Draft Release 1 を、英語の勉強がてら日本語訳してみました。
今回は後編として、第5章~第6章(最後まで)を訳します。

前編(第1章~第2章)はコチラ↓
JSR 371(MVC 1.0) Early Draft version 1.0 の日本語訳(前編) - Java EE 事始め!
中編(第3章~第4章)はコチラ↓
JSR 371(MVC 1.0) Early Draft version 1.0 の日本語訳(中編) - Java EE 事始め!

Chapter 5 アプリケーション

この章では、MVCアプリケーションの概念およびJAX-RSアプリケーションとどう関連があるかを説明します。

5.1 MVCアプリケーション

MVCアプリケーションは、1つ以上の@Controllerで注釈されたJAX-RSリソースと、JAX-RSアプリケーションと同様に、0個以上のプロバイダーを含んでいます。@Controllerで注釈されたJAX-RSリソースが存在しない場合、結果的に代わりとしてアプリケーションはJAX-RSアプリケーションとなります。通常、JAX-RSに適用される全ての事柄はMVCアプリケーションにも適用されます。MVCアプリケーションは、MVCコントローラーとJAX-RSリソースメソッドが混在する「ハイブリッド」にすることができます。
アプリケーションを構成するコントローラーとプロバイダーは、アプリケーションが提供するJAX-RSのApplicationクラスのサブクラスによって設定されます。実装は、コントローラーを配置するための代わりの仕組みを提供することが許されていますが、JAX-RSと同様、Applicationのサブクラスを使うことが、ポータビリティを保証する唯一の方法です。
JAX-RS仕様のServletのセクションで説明されている全てのルールが、MVCにも同様に適用されます。このセクションでは、Servlet 3 framework pluggabilityの仕組みを使うことを推奨しており、Applicationのサブクラスが存在する場合としない場合のケースの意味論を説明しています。
MVCコントローラーが生きるアプリケーションのURL空間内のパスは、Applicationサブクラスの@ApplicationPathアノテーションか、web.xmlにurl-pattern要素の一部に指定します。MVCアプリケーションは、空でないパスまたはパターンを使うべきです。例えば、"/"または"/*"は、可能な限り避けるべきです。
この理由は、MVC実装は多くの場合、サーブレットコンテナにリクエストをフォワードし、これらの値の使用は、JAX-RSサーブレットよってもう1回フォワードされたリクエストを不要に処理することを可能にします*1。ほとんどのJAX-RSアプリケーションはこれらの値を使うことを避けており、多くは"/resources"または"/resources/*"を使う慣習です。一貫性のため、MVCアプリケーションも同様にこれらのパターンを使うことが推奨されます。

5.2 MVCのプロバイダー

実装は、MVCの意味論を実装する目的で、標準のJAX-RSパイプラインを変更するために、独自のプロバイダーを使用することは自由です。実装とアプリケーションプロバイダーを混在させる時はいつでも、使用している優先度に従った正しい順序で実行されていることを保証することに、注意を払うべきです。

Editors Note 5.1

MVCに関連したいかなるプロバイダーもの優先度の範囲も定義されるべきでしょうか?

Chapter 6 ビューエンジン

この章では、ビューがMVCで処理される仕組みとしてのビューエンジンの概念について説明します。利用可能なビューエンジンはCDIを通して拡張可能であり、他のフレームワークと同様に、追加のビュー言語サポートを提供することも可能です。

6.1 導入

ビューエンジンは、ビューの処理に責任を持ちます。この背景では、処理は以下を必要とします。(i)ビューの配置および読み込み、(ii)必要となるモデルの準備、(iii)ビューを 描画しクライアントに結果を書き込んで返す。
実装はJSPとFaceletsのビューエンジンを組み込みでサポートしなければなりません。追加のエンジンはCDIをベースとした拡張機能としてサポートすることができます。すなわち、javax.mvc.engine.ViewEngineインターフェイスを実装しているCDIビーンは、そのsopportメソッドの呼び出しによって処理の対称に出来ると考えなければなりません(supportメソッドがfalseを返すエンジンを除く)。
すべてのMVCビューエンジンが実装しなければならないインターフェイスはこちらです。

public interface ViewEngine {

  boolean supports(String view);

  void processView(ViewEngineContext context) throws ViewEngineException;
}

6.2 選択アルゴリズム

2.1.2で説明したように、Viewableはビューに関する情報をカプセル化します。コントローラーメソッドからの戻り値で利用できるすべての型は、いずれにしても、コンストラクタの呼び出しによりViewableに変換されます。よって、下記のアルゴリズムは入力がViewableだと仮定します。
実装はViewableに適したビューエンジンを見つけるために、下記のステップで振舞うべきです。

  1. ViewableのgetViewEngineメソッドがnullでない値を返した場合、そのビューエンジンを返します。
  2. そうでなければ、CDIを通して利用可能なjavax.mvc.engine.ViewEngineの全インスタンスを探します。
  3. 前のステップで見つかった全てのビューエンジンのsupportsメソッドを呼び出し、falseを返すものを廃棄します。
  4. もし結果セットが空ならば、nullを返します。
  5. そうでなければ、ビューエンジンクラスに付加された@Priorityアノテーションからの整数値の降順に、結果セットを並び替えます(アノテーションが無い場合はPrioritues.DEFAULTをデフォルト値とします)。
  6. ソートされた結果セットの1番目の要素を返します。これが、与えられたViewableをサポートする優先度の一番高いビューエンジンです。

もし、Viewableを処理できるビューエンジンが見つからなかった場合、ビューを処理するための他の縮退手段として、実装はRequestDispatcherを使用してサーブレットコンテナにリクエスト・レスポンスのペアをフォワードして戻すことが要求されます。
processViewメソッドは、サーブレットコンテナ下からのHTTPリクエスト・レスポンスと同様に、ViewEngineContextの処理、ビューを含める、Modelsへの参照などに必要なすべての情報を持っています。実装は、processViewの実行中にスローされる例外をキャッチし、ViewEngineExceptionとして再スローしなければなりません。
ビューの描画フェーズに先立って、Mogels内で利用可能な全てのエントリーは、処理されているビューで利用可能になるようにバインドされなければなりません。このための抽出の仕組みは、現在のビューエンジン実装に依存します。JSPおよびFaceletsの組み込みビューエンジンの場合、Models内のエントリーは、HttpServletRequest.setAttribute(String, Object)の呼び出しによってバインドされます。このメソッドを呼ぶことで、名前が付けられたモデルをEL式からアクセスすることが出来ます。
コントローラーメソッドによって返されたビューは、アプリケーションアーカイブ内のパスを表します。パスが相対パスであり、"/"で始まっていない場合、実装はビューのパスをViewEngine.DEFAULT_VIEW_FOLDER(この値は"/WEB-INF/views"にセットされています)に解決します。パスが絶対パスの場合、これ以上の処理は要求されません。ビューを静的リソースとして直接アクセスされることを避けるために、相対パスおよびWEB-INF配下を使用することが推奨されます。

*1:原文は「The reason for this is that MVC implementations often forward requests to the Servlet container, and the use of these values may result in the unwanted processing of the forwarded request by the JAX-RS servlet once again.」