新人SEの学習記録

14年度入社SEの学習記録用に始めたブログです。もう新人じゃないかも…

学習記録:Spring

[学習記録] Spring

内容: 6章 プレゼンテーション層の設計と実装 ー Spring MVC

Spring MVCの概要
  • Spring MVCの設計
    • Strutsなどと同様、J2EEパターンのFrontControllerパターンに基づく
    • 役割ごとに明確にクラスが分割され、クラス間の関連が疎結合となっている点が特徴
    • Model/View/Controllerに各々インタフェースが定義され、互いの実装に依存しない
@Controller
public class HogeController {
    @Autowired
    private HogeService hogeService;

    @RequestMapping(value = "/hoge", method = RequestMethod.GET)
    public String showAllHoge(@RequestParam("userId") int userId, Model model) {

    /* 以下省略 */

    }
}
  • Spring MVCの自由度
    • インタフェースのimplementsやクラスの継承が必要なフレームワークでは、制限が多い
    • オーバライドするメソッドが固定なので、1クラス1メソッドしか定義できなかったり、メソッド名や引数が固定だったりする
    • Spring MVCのControlllerクラスは非常に自由度が高い
    • メソッドはいくつでも実装可能、メソッド名も何でもOK、引数も必要なものだけ定義すればよい
    • リクエストパラメータを直接引数として定義できたり、URLの一部を引数として受け取れたり
  • Spring MVCとREST
    • Spring MVCのControllerの特徴は、URLとメソッドを直接結びつけていること
    • REST(Representational State Transfer)、Web上の情報をリソースとして捉え、その識別子としてURLを割り当てる
    • ユーザIDが1のユーザ情報を取得するときには、http://foo.bar.hoge/user/1にGETメソッドでアクセス
    • RESTには1)URLを自由に決定できる、2)HTTPメソッドに応じて処理を切り替えられる、3)URLの一部を容易に取り出せることが必要
    • Spring MVCはこの全てを満たしている
Spring MVCの登場人物と動作概要
  1. DispatcherServletがブラウザからリクエストを受け付け
  2. リクエストされたURLをHandlerMappingオブジェクトに渡して呼び出し対象のControllerオブジェクトを取得
  3. DispatcherServletは取得したControllerオブジェクトの中で、URLに該当するメソッドを実行
  4. Controllerオブジェクトは処理を実行し、結果をModelオブジェクトに格納する。最後にView名を返す
  5. DispatcherServletはControllerから返されたView名をViewResolverに渡し、Viewオブジェクトを取得する
  6. DispatcherServletはViewオブジェクトに画面表示を依頼
  7. Viewオブジェクトは該当するViewを呼び出して画面表示を依頼
  8. ビューはModelオブジェクトから画面表示に必要なオブジェクトを取得し、画面表示処理を実行する
  • 上記の処理の中で、開発者が記述する必要があるのは
    • 個々のURLに対応するController
    • Controllerが呼び出すビジネスロジック
    • 最終的に画面表示するビュー
Controllerの概要とModelオブジェクト
  • Controllerの役割
    • クライアントからのリクエストに応じてプレゼンテーション層のアプリケーション処理を実行
    • 検索処理であれば検索条件をリクエストから取得し、ビジネスロジックの検索メソッドを実行
    • 最後にView名を返す
@Controller
public class HogeController {

	@Autowired
	private UserService userService;

	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String hoge(Model model) {
		List<User> list = userService.findAll();

		model.addAttribute("userList", list);

		return "list";
	}
}
  • @RequestMapping
    • クラスにも設定可能。その場合、メソッドにはクラスに指定したURLのサブURLを指定する
    • value属性の他、method属性(HTTPメソッド)、param属性(リクエストパラメータ)を指定可能
    • 他の属性指定がない場合には"value ="を省略可
    • {}で複数URLを割り当てることも可能
    • URIテンプレート: 一部が動的に変わる部分を{名前}の形式で指定し、その部分を取得できる
@RequestMapping("/sample")
class SampleController {
  
  @RequestMapping
  public String method01() {...}  // /sampleで実行される

  @RequestMapping(value = "/foo")
  public String method02() {...}  // /sample/fooで実行される

  @RequestMapping("/bar")
  public String method03() {...}  // /sample/barで実行される。"value ="の省略

  @RequestMapping({"/hoge1", "/hoge2"})
  public String method04() {...}  // /sample/hoge1, /sample/hoge2で実行される

  @RequestMapping(value = "/foo", method=HttpMethod.POST)
  public String method05() { ... } // POSTメソッド時に実行される

  @RequestMapping(value = "/foo", params = "param")
  public String method06() { ... } // "param"がリクエストパラメータに含まれる場合に実行される

  @RequestMapping(value = "/foo", params = "param=hoge")
  public String method07() { ... } // "param=hoge"がリクエストに含まれる場合に実行される

  @RequestMapping(value = "/foo/bar/{value}")
  public String method08(@PathVariable String value) { ... } // /foo/bar/1 や /foo/bar/hoge で実行される
                                                                                              // 引数のvalueに{value}の値が入る
}
  • Controllerのメソッドの"Model"
    • MVCのModelに相当するオブジェクト
    • Cotrollerからビューに受け渡すオブジェクトを保持する役割
    • その他、Cotorollerメソッドで指定可能な引数は以下
説明 アノテーション 使用例
URIテンプレートを使ったURLの変数値 任意 @PathVariable(変数名) foo(@PathVariable int userId)
HTTPリクエストパラメータ 任意 @RequestParam(パラメータ名) foo(@RequestParam("userId") int userId)
HTTPリクエストのヘッダ 任意 @RequestHeader(ヘッダ名) foo(@RequestHeader("User-Agent") String userAgent)
HTTPリクエストのメッセージボディ 任意 @RequestBody foo(@RequestBody User user)
クッキー 任意 @Cookie(クッキー名) foo(@Cookie("jsessionid") String Session)
ModelAttribute 任意 @ModelAttribute(モデル名) foo(@ModelAttribute("editedUser") User user)
アップロードファイル MultipartFile @RequestParam(パラメータ名) foo(@Requestparam("hoge") MultipartFile uploaded)
HttpEntity HttpEntity
Model Model
Session管理 SessionStatus
エラー Errors
WebRequest WebRequest
Servlet API HttpServletRequest, HttpServletResponse, HttpSession
ロケール Locale
リクエスト・レスポンスへのストリーム Reader/Writer
認証 Principal
  • メソッドの戻り値で表示するビューを指定
    • ViewResolverがViewオブジェクトを決定し、ビューを表示する
    • redirect:[URL] : 指定URLへリダイレクトする
    • forward:[URL]: 指定URLへフォワードする。単純にView名だけreturnしてもこっちになる
ViewとViewResolver
  • Viewインタフェースを実装したViewオブジェクトが、開発者が作成したビューを呼び出す
    • JSTLで作成したビューであればJstlViewクラスのオブジェクトがViewオブジェクトとして振る舞う
    • Spring MVCでは多くのビューテクノロジに応じたViewクラスを用意
ビューテクノロジ クラス名 説明
JSP、その他 InternalResourceView Webコンテナ上で管理されているリソースに対してforwardすることで表示を行う
JSTLベースJSP JstlView InternalResourceViewを継承。JSTLで書かれたJSPにはこれを使用
Velocity VelocityView Velocityのテンプレートを使って結果を表示
Apache Tiles TilesView Apache Tilesのテンプレートを使って結果を表示
XSLT XsltView XSLTで変換した結果のXMLを表示
XML MarshallingView SpringのO/Xマッピング機能で変換した結果のXMLを表示
Jackson(JSON形式) MappingJacksonJsonView Jacksonで変換した結果のJSONを表示
Apache POI(Excel形式) AbstractExcelVIew Apache POIで変換した結果のExcelを表示
iText(PDF形式) AbstractPdfView iTextで変換した結果のPDFを表示
  • Controllerクラスの戻り値では、Viewオブジェクトを返すこともできる
    • return new JstlView("/hogehoge/hoge.jsp");
    • この方法だとControllerとビューテクノロジが密接に結合してしまい、独立性が保たれない
    • そこで、ControllerからはView名だけを返すようにし、ViewResolverオブジェクトがViewオブジェクトを生成するように
    • ViewResolverの設定を変えてやることで、ある画面ではJSP、ある画面ではVelocityで結果を表示するようにできる
  • 主なViewResolverクラス
クラス名 説明 設定方法
UrlBasedViewResolver 指定prefix/suffixを元に作成したURLのViewオブジェクトを返す UrlBasedViewResolverのプロパティとして定義
ResourceBundleViewResolver Javaのリソースバンドル形式の設定ファイルを元にViewオブジェクトを決定 リソースバンドルファイルとして定義
XmlViewResolver/BeanNameViewResolver DIコンテナからBean名がView名のViewオブジェクトを返す Bean定義ファイルとして定義
ContentNegotiatingViewResolver HTTPリクエストのヘッダを元にViewオブジェクトを選択 各ViewResolverに定義