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/images/mvc.png

 

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
  • などなど.....

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-return-types

@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"; 
    }
}