Spring学習メモ(MVCフレームワーク:全体像、コントローラ)
学習メモ。参考にしたのはオフィシャルリファレンス。
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html
SpringのMVCフレームワークは、他のWeb MVCフレームワークと同じように、リクエストドリブンでServlet(DispatcherServlet)がコントローラの割り当てなどを行う。ただし、SpringのDispatcherServletはSprincのIoCコンテナと統合されているため、Springの機能をすべて使うことができる。
全体像
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html
フロントコントローラデザインパターンを採用している。Front controllerに当たるのがDispatcherServlet。
アプリケーション内には複数のDispatcherServletを持つことができ、web.xmlでURLが割り当てられる。以下の例では、/rest/で始まるURLはServlet「rest」に割り当てられる。
web.xml
<web-app> <!-- descriptions.. --> <servlet> <servlet-name>rest</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <!-- descriptions.. --> <servlet-mapping> <servlet-name>rest</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> <!-- descriptions.. --> </web-app>
rest-servlet.xml (restサーブレットに対応するConfigファイル)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> <mvc:annotation-driven > </mvc:annotation-driven> <context:component-scan base-package="com.myapplication.controller" /> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" id="handlerMapping"> <property name="alwaysUseFullPath" value="true"> </property> </bean> </beans>
各DispatcherServletは、それぞれ固有のWebApplicationContext(IoCコンテナ)を持ち、これにコントローラ、ビューレゾルバ、マッピングなどが登録されている。
コントローラ
@Controllerと@RequestMappingアノテーションで、リクエストに対応するクラスとメソッドを指定する。@Controller(ステレオタイプアノテーション)のスキャニングを有効にするため、XMLにcomponent-scanの設定が必要。
以下の場合、URI「~/Abc」がAbcControllerのメソッドabc()に割り当てられる。
@Controller public class AbcController { @RequestMapping("/Abc") public String abc(Model model) { model.addAttribute("message", "string added by abc controller!"); return "helloWorld"; } }
@RequestMappingはClass定義に付けることもできる。
@Controller @RequestMapping("/Abc") public class AbcController { .... }
URIのパターンマッチング例。@PathVariableを付けると、対応するURI変数が引数にバインドされる。
@RequestMapping(value="/abc/{Id}", method=RequestMethod.GET) public String abc(@PathVariable String Id, Model model) { model.addAttribute("id", Id); return "helloWorld"; }
HTTPメッセージ内のパラメタやヘッダでフィルタリングもできる。
@RequestMapping(value="/abc/{Id}", method=RequestMethod.GET, params="myParam=myValue")
@RequestMapping(value="/abc/{Id}", method=RequestMethod.GET, headers="myHeader=myValue")
@PathVariableの他にも、メソッドの引数にはさまざまな型を使うことができる。
- Request or Response object(Servlet API)
- Session object of HTTP session(Servlet API)
- WebRequest or NativeWebRequest objects
- java.util.locale
- java.util.timezone
- java.io.InputStream/java.io.Reader
- などなど.....
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-arguments
メソッドの返り値にも、さまざまな型が使える。
- ModelAndView object
- Model object
- Map object
- View object
- HTTP response body
- などなど.....
@RequestBodyを付けると、HTTPリクエストそのものをStringで取得できる。
@RequestMapping(value = "/Abc", method = RequestMethod.PUT) public void abc(@RequestBody String body, Writer writer) throws IOException { writer.write(body); }
逆に、@ResponseBodyを付けると、HTTPレスポンスに返り値(XMLやJSONなど)がそのまま書き込まれる。
@RequestMapping(value = "/Abc", method = RequestMethod.PUT) @ResponseBody public String abc() { return "helloWorld"; }
クラス内すべてのメソッドに@ResponseBodyを付ける代わりに、クラス宣言部の@Controllerを@RestControllerに変えることができる。REST APIを実装するときに便利。
@RestController public class AbcController { @RequestMapping(value = "/Abc", method = RequestMethod.PUT) public String abc() { return "helloWorld"; } }