SpringMVCのアノテーションと非同期実行と試験
SpringMVCのアノテーション
- @Controller
- MVCのコントローラとなるクラスに付与する
- @RestController
- Restfulサービスを構築する際のMVCコントローラクラスに付与する
- @Controllerと@ResponseBodyを付与したサイト同等
- @RequestMapping
- 特定の「URI(value)、「HTTPメソッド(method)」、「HTTPヘッダ(headers)」、「リクエストパラメータ(params)」を処理するメソッドに付与
- 例)headersがAND表記の場合
- @RequestMapping(value="/owners/{ownerId}", method=RequestMethod.GET, headers={"Accept=application/*","Content-Type=text/*"})
- 例)headersがOR表記の場合
- また、「consumes(クライアントから送付されたメディアタイプを指定)」、「produces(クライアントへ返すメディアタイプを指定)」も指定できる
- 例)JSONで受けてJSONで返す場合
- @RequestParam
- URLパラメータをメソッド引数に注入できる
- @PathVariable
- @RequestHeader
- 特定のHTTPヘッダをメソッド引数に注入できる
- @RequestBody
- HTTPリクエストボディをメソッド引数に注入できる
- @ResponseBody
- オブジェクトをHTTPレスポンスのボディとして返却できる
- @ResponseStatus
- メソッドに付与してHTTPレスポンスのステータスを指定できる
- 例)
- @ResponseStatus(value = HttpStatus.BAD_RESUEST)
- @ExceptionHandler
- @CookieValue
- @InitBinder
- @ModelAttribute
※@InitBinderと@ModelAttributeについてはまだよくわからん。下記参照。
https://sites.google.com/site/soracane/home/springnitsuite/spring-mvc/04-ji-ben-gai-nian-controllerno-chu-lifuro
@Controller @RequestMapping("/pizzas") public class PizzaController { // POST /pizzas/bake?temp=400 @RequestMapping(value = "/bake", method = POST) public void bake(@RequestParam Integer temp) { ... } }
@Controller @RequestMapping("/pizzas") public class PizzaController { // POST /pizzas/bake/400 @RequestMapping(value = "/bake/{temp}", method = POST) public void bake(@PathVariable Integer temp) { ... } }
@Controller @RequestMapping("/pizzas") public class PizzaController { // GET /pizzas @RequestMapping(method = GET, produces = "application/json") public @ResponseBody List<Pizza> list() { ... } }
@Controller @RequestMapping("/pizzas") public class PizzaController { // GET /pizzas @RequestMapping(method = GET, produces = MediaType.APPLICATION_JSON_VALUE ) public @ResponseBody List<Pizza> list() { ... } }
@Controller @RequestMapping("/pizzas") public class PizzaController { // GET /pizzas @ResponseStatus(HttpStatus.CREATED) @RequestMapping(method = PUT, consumes = "application/json" ) public void create(@RequestBody Pizza pizza) { ... } }
@Controller public class PizzaController { @RequestMapping(method = RequestMethod.GET ) public String validateForm(@ModelAttribute("userDetails") UserDetails details) { ... } @ModelAttribute("userDetails") public UserDetails getUserDetails(HttpServletRequest request) { UserDetails user = new UserDetails(); user.setFirstName(request.getParameter("firstName")); return user; } }
- コントローラクラスのメソッドにて引数に指定可能な型:
- コントローラクラスのメソッドにて返り値に指定可能な型:
- ModelAndView, Model, java.util.Map, View
- String
- void
- HttpEntity, ResponseEntity
- 等
★SpringMVCのControllerでURLを厳密に判定する
http://d.hatena.ne.jp/eiryu9/20130120/1358651987
SpringMVCの非同期実行
Async MVC Proccessing: Callable
@Controller @RequestMapping("/pizzas") public class PizzaController { @RequestMapping(value = "/orders", method = POST ) @ResponseBody public Callable<String> upload(MultipartFile file) { return new Callable<Pizza>() { public Pizza call() throws Exception { ... return pizza; } } } }
Async MVC Proccessing: DeferredResult(延期された結果)
@RequestMapping(value = "/orders", method = POST ) @ResponseBody public DeferredResult quotes() { DeferredResult deferredResult = new DeferredResult(); // deferredResultにQueueやMapをaddする return deferredResult; } // 他のスレッドで返り値をDeferredResultにsetする deferredResult.set(data);
Async MVC Proccessing: AsyncTask
@RequestMapping(name = "/upload", method = RequestMethod.POST ) public AsyncTask<Foo> processUpload(MultipartFile file) { TaskExecutor asyncTaskExecutor = new AsyncTaskExecutor(...); return new AsyncTask<Foo>( 1000L, // timewout asyncTaskExecutor, // thread pool new Callable<Foo>(){...} // thread ); }
SpringMVC UTのざっくりした流れ
- JUnitコードのランナーとしてSpringJUnit4ClassRunnerを使えば、DIコンテナが勝手にいい感じで起動してくれる。
- HttpServletRequest、HttpServletResponseのモックをインスタンス化する。
- モックのrequestにテスト対象のURIやパラメータをセット
- そのrequestオブジェクトをリクエストハンドラに渡すと疑似リクエストが発生し、コントローラクラスに渡される。
- コントローラの該当メソッドが戻り値として返すModelAndViewオブジェクトにレスポンス情報が入っている。
- このレスポンス情報をAssertすればよい。
参考:
Spring MVCのススメ
http://d.hatena.ne.jp/ryoasai/20101121/1290317629