)として応答する場合、レスポンスデータの生成(ダウンロード処理)を行うViewを作成し、処理を委譲することを推奨する。Modelに追加し、ダウンロード処理を行うViewのView名を返却する。Frameworkから提供されているBeanNameViewResolverを使用する。説明(1)BeanNameViewResolverを定義する。BeanNameViewResolverは、返却されたView名に一致するBeanをアプリケーションコンテキストから探してViewを解決するクラスとなっている。TilesViewResolverと併用する場合は、これらのViewResolverより、高い優先度を指定する事を推奨する。指定することで、InternalViewResolverより先にBeanNameViewResolverによるView解決が行われる。4.1から追加された<mvc:bean-name>要素を使用して、BeanNameViewResolverを定義する。<mvc:view-resolvers>要素を使用してViewResolverを定義する場合は、子要素に指定するViewResolverの定義順が優先順位となる。上記例では、JSP用のInternalViewResolverを定義するための要素(<mvc:jsp>)より上に定義することで、JSP用のInternalViewResolverより先にBeanNameViewResolverによるView解決が行われる。本ガイドラインでは<mvc:view-resolvers>を使用することを推奨する。(5)でBean登録されたViewインスタンスによって生成されたデータがダウンロードデータとして応答される。(5)コンポーネントの名前にView名を指定して、ViewオブジェクトをBeanとして登録する。インスタンスがBean登録される。(6)Viewの実装例。継承し、Excelデータを生成するViewクラスの実装となる。いう点がポイントとなる。業務処理の実装はServiceで行い、Controllerでは業務処理が実装されているServiceのメソッドを呼び出す。NoteControllerは、基本的には画面遷移の決定などの処理のルーティングとModelの設定のみ実装することに徹し、可能な限りシンプルな状態に保つこと。この方針で統一することにより、Controllerで実装すべき処理が明確になり、開発規模が大きくなった場合でもControllerのメンテナンス性を保つことができる。Controllerで実装すべき処理を以下に4つ示す。Validationで検証を行う。相関チェックの実装自体はControllerのハンドラメソッドで行うことはないが、相関チェックを行うValidatorをorg.springframework.web.bind.WebDataBinderに追加する必要がある。説明(1)相関チェックを行うValidatorをInjectする。WebDataBinderに追加する。WebDataBinderに追加しておくことで、ハンドラメソッド呼び出し前に行われる入力チェック処理にて、(1)で追加したValidatorが実行され、相関チェックを行うことが出来る。業務処理が実装されているServiceをInjectし、InjectしたServiceのメソッドを呼び出すことで業務処理を実行する。メソッドを呼び出し、業務処理を実行する。formから送信されたデータは直接ドメインオブジェクトにバインドするのではなく、フォームオブジェクトにバインドする方法を推奨している。そのため、ControllerではServiceのメソッドに渡すドメインオブジェクトにフォームオブジェクトの値を反映する処理を行う必要がある。説明(1)Serviceの引数となるドメインオブジェクトを生成し、フォームオブジェクトにバインドされている値を反映する。(2)Serviceのメソッドを呼び出し業務処理を実行する。Modelに追加する。ドメインオブジェクトへ値を反映する処理は、Controllerのハンドラメソッド内で実装してもよいが、コード量が多くなる場合はハンドラメソッドの可読性を考慮してHelperクラスのメソッドに処理を委譲することを推奨する。以下にHelperメソッドに処理を委譲した場合の例を示す。説明(1)ControllerにHelperクラスのオブジェクトをInjectする。(2)InjectしたHelperクラスのメソッドを呼び出すことで、ドメインオブジェクトへの値の反映を行っている。Helperクラスに処理を委譲することで、Controllerの実装をシンプルな状態に保つことができる。(3)ドメインオブジェクトを生成した後に、Serviceクラスのメソッド呼び出し業務処理を実行している。NoteHelperクラスに処理を委譲する以外の方法として、Bean変換機能を使用する方法がある。formの項目にバインドするデータはドメインオブジェクトではなく、フォームオブジェクトを使用する方法を推奨している。そのため、ControllerではServiceのメソッドから返却されたドメインオブジェクトの値をフォームオブジェクトに反映する処理を行う必要がある。説明(1)業務処理が実装されているServiceのメソッドを呼び出し、ドメインオブジェクトを取得する。(2)取得したドメインオブジェクトの値をフォームオブジェクトに反映する。(3)表示のみ行う項目がある場合は、データを参照できるようにするために、Modelにドメインオブジェクトを追加する。Note画面に表示のみ行う項目については、フォームオブジェクトに項目をもつのではなく、Entityなどのドメインオブジェクトから直接値を参照することを推奨する。コード量が多くなる場合はハンドラメソッドの可読性を考慮してHelperクラスのメソッドに委譲することを推奨する。説明(1)ドメインオブジェクトの値をフォームオブジェクトに反映するためのメソッドを呼び出す。(2)ドメインオブジェクトの値をフォームオブジェクトに反映するためのメソッドにて、ドメインオブジェクトの値をフォームオブジェクトに反映する。NoteHelperクラスに処理を委譲する以外の方法として、Bean変換機能を使用する方法がある。フォームオブジェクトの実装¶フォームオブジェクトはHTML上のformを表現するオブジェクト(JavaBean)であり、以下の役割を担う。formから参照できるようにする。formから送信されたリクエストパラメータを保持し、ハンドラメソッドで参照できるようにする。フォームオブジェクトの実装について、以下4点に着目して説明する。フォームオブジェクトの作成方法¶フォームオブジェクトはJavaBeanとして作成する。フォームオブジェクトに定義するフィールドの型は、java.lang.Stringだけではなく、任意の型で定義することができる。Frameworkは、以下の3つの仕組みを使って型変換を行っており、基本的な型への変換は標準でサポートされている。各変換機能の詳細については、リンク先のページを参照されたい。formの項目のみ保持することを推奨する。フォームオブジェクトに画面表示のみ行う項目の値を設定した場合、フォームオブジェクトをHTTPセッションオブジェクトに格納する際にメモリを多く消費する事になり、メモリ枯渇の原因になる可能性がある。画面表示のみの項目は、Entityなどのドメイン層のオブジェクトをリクエストスコープに追加(Model.addAttribute)することでHTML(JSP)にデータを渡すことを推奨する。フィールド単位の数値型変換¶@NumberFormatアノテーションを使用することでフィールド毎に数値の形式を指定することが出来る。formから送信されるリクエストパラメータの数値形式を指定する。形式を指定しているので、「,」でフォーマットされた値をバインドすることができる。Integerオブジェクトがバインドされる。数値のスタイルを指定する。詳細は、NumberFormat.StyleのJavadocを参照されたい。Javaの数値形式を指定する。詳細は、DecimalFormatのJavadocを参照されたい。フィールド単位の日時型変換¶@DateTimeFormatアノテーションを使用することでフィールド毎に日時の形式を指定することが出来る。formから送信されるリクエストパラメータの日時形式を指定する。2013年10月1日のDateオブジェクトがバインドされる。ISOの日時形式を指定する。詳細は、DateTimeFormat.ISOのJavadocを参照。Javaの日時形式を指定する。詳細は、SimpleDateFormatのJavadocを参照されたい。style日付と時刻のスタイルを2桁の文字列として指定する。1桁目が日付のスタイル、2桁目が時刻のスタイルとなる。スタイルとして指定できる値は以下の値となる。java.text.DateFormat.SHORTと同じ形式となる。java.text.DateFormat.MEDIUMと同じ形式となる。java.text.DateFormat.LONGと同じ形式となる。java.text.DateFormat.FULLと同じ形式となる。省略を意味するスタイル。Controller単位の型変換¶@InitBinderアノテーションを使用することでController毎に型変換の定義を指定する事も出来る。付与したメソッド用意すると、バインド処理が行われる前にこのメソッドが呼び出され、デフォルトの動作をカスタマイズすることができる。指定しているので、「,」でフォーマットされた値をバインドすることができる。(3)@InitBinderアノテーションのvalue属性にフォームオブジェクトの属性名を指定することで、フォームオブジェクト毎にデフォルトの動作をカスタマイズすることもできる。いう属性名のフォームオブジェクトに対するバインド処理が行われる前にメソッドが呼び出される。Validationを使用して行うため、フィールドの制約条件を示すアノテーションを指定する必要がある。beanと呼び、@ModelAttributeアノテーションを使うことで結びつけることができる。beanの初期化は、@ModelAttributeアノテーションを付与したメソッドで行う。このようなメソッドのことを本ガイドラインではModelAttributeメソッドと呼び、setUpXxxFormというメソッド名で定義することを推奨する。説明(1)Modelに追加するための属性名は、クラス名の先頭を小文字にした値(デフォルト値)が設定される。返却したオブジェクトは、model.addAttribute(form)相当の処理が実行されModelに追加される。(2)Modelに追加するための属性名を指定したい場合は、@ModelAttributeアノテーションのvalue属性に指定する。form)相当の処理が実行されModelに追加される。デフォルト値以外の属性名を指定した場合、ハンドラメソッドの引数としてフォームオブジェクトを受け取る時に@ModelAttribute("xxx")の指定が必要になる。(3)ModelAttributeメソッドは、ハンドラメソッドと同様に初期化に必要なパラメータを渡すこともできる。例では、@CookieValueアノテーションを使用してCookieの値をフォームオブジェクトに設定している。Noteフォームオブジェクトにデフォルト値を設定したい場合はModelAttributeメソッドで値を設定すること。例の(3)ではCookieから値を取得しているが、定数クラスなどに定義されている固定値を直接設定してもよい。NoteModelAttributeメソッドはController内に複数定義することができる。各メソッドはControllerのハンドラメソッドが呼び出される前に毎回実行される。WarningModelAttributeメソッドはリクエスト毎にメソッドが実行されるため、特定のリクエストの時のみに必要なオブジェクトをModelAttributeメソッドを使って生成すると、無駄なオブジェクトの生成及び初期化処理が行われる点に注意すること。特定のリクエストのみで必要なオブジェクトについては、ハンドラメソッド内で生成しModelに追加する方法にすること。formへのバインディング方法¶Modelに追加されたフォームオブジェクトは<form:xxx>タグを用いて、HTML(JSP)のformにバインドすることができる。libraryを参照されたい。説明(1)<form:form>タグを使用するためのtaglibの定義を行う。(2)<form:form>タグのmodelAttribute属性には、Modelに格納されているフォームオブジェクトの属性名を指定する。(3)<form:input>タグのpath属性には、フォームオブジェクトのプロパティ名を指定する。formから送信されたリクエストパラメータは、フォームオブジェクトにバインドし、Controllerのハンドラメソッドの引数に渡すことができる。説明(1)フォームオブジェクトにリクエストパラメータが反映された状態で、Controllerのハンドラメソッドの引数に渡される。(2)ModelAttributeメソッドにて属性名を指定した場合、@ModelAttribute("xxx")といった感じで、フォームオブジェクトの属性名を明示的に指定する必要がある。WarningModelAttributeメソッドで指定した属性名とメソッドの引数で指定した属性名が異なる場合、ModelAttributeメソッドで生成したインスタンスとは別のインスタンスが生成されるので注意が必要。ハンドラメソッドで属性名の指定を省略した場合、クラス名の先頭を小文字にした値が属性名として扱われる。org.springframework.validation.BindingResultに格納される。説明(1)フォームオブジェクトの直後にBindingResultを宣言すると、フォームオブジェクトへのバインド時のエラーと入力チェックエラーを参照することができる。(2)BindingResult.hasErrors()を呼び出すことで、フォームオブジェクトの入力値のエラー有無を判定することができる。フィールドエラーの有無、グローバルエラー(相関チェックエラーなどのクラスレベルのエラー)の有無を個別に判定することもできるので、要件に応じて使い分けること。Viewの実装¶Viewは以下の役割を担う。クライアントに応答するレスポンスデータ(HTML)を生成する。Viewはモデル(フォームオブジェクトやドメインオブジェクトなど)から必要なデータを取得し、クライアントが描画するために必要な形式でレスポンスデータを生成する。JSPの実装¶クライアントにHTMLを応答する場合は、JSPを使用してViewを実装する。Frameworkより提供されているので、提供されているクラスを利用する。以下に、基本的なJSPの実装方法について説明する。formへフォームオブジェクトをバインドする入力チェックエラーを表示する処理結果のメッセージを表示するコードリストを表示する固定文言を表示する条件によって表示を切り替えるコレクションの要素に対して表示処理を繰り返すページネーション用のリンクを表示する権限によって表示を切り替える本章では代表的なJSPタグライブラリの使い方は説明しているが、全てのJSPタグライブラリの説明はしていないので、詳細な使い方については、それぞれのドキュメントを参照すること。libraryから提供されている<form:form>タグを使う際は、必ずaction属性を指定すること。scripting)の脆弱性が存在する。(NVD)のCVE-2014-1904を参照されたい。MVC(3.2.10.RELEASE以上)に依存しているため、本脆弱性は存在しない。全てのJSPで必要となるディレクティブの宣言などを行うためのJSPを作成する。要素に指定することで、個々のJSPで宣言する必要がなくなる。このファイルはブランクプロジェクトで提供している。説明(1)JSTLのJSPタグライブラリを宣言している。FrameworkのJSPタグライブラリを宣言している。(3)共通ライブラリから提供しているJSPタグライブラリを宣言している。(4)インクルード用のJSP(/WEB-INF/views/common/include.jsp)に指定した内容が、各JSP(<url-pattern>で指定されているファイル)の先頭にインクルードされる。