Spring 2.5 MVC コントローラ アノテーション
あまり話題になることのない Spring MVCだが、私は「DIが可能でちょっと便利なサーブレット」として使うことがある。Spring 2.5では、アノテーションでコントローラクラスの使われ方を設定できるようになり楽になったので情報をメモしておく。
参考: 13.12. Annotation-based controller configuration
web.xmlの設定
Spring 2.0の時と同じで、DispatcherServletをservlet登録し、URIにマッピングする。ただし Spring 2.5の配布では、DispatcherServletは spring.jarに入っておらず spring-webmvc.jarに収録されているため、spring.jarの他に spring-webmvc.jarもプロジェクトに加えること。
アノテーションで設定をする場合、コントローラは bean要素でただロードさせるだけで良い。
<bean class="com.acme.hello.web.HelloController" />
また、「このパッケージ以下にあるコントローラクラスを全部」のような指定もできる。
コントローラクラスには @Controllerアノテーション(org.springframework.stereotype.Controller)をつけてやる。
1種類のURIに1個のコントローラを割り当てる場合はコントローラクラスに、1個のコントローラで様々なURIの処理を行うにはコントローラクラスのpublicメソッドにそれぞれ @ResultMappingアノテーションでURIを指定する。ここでは後者を例にとる。
HttpServletRequest(IN)
HttpServletResponse(OUT)
org.springframework.web.context.request.WebRequest (IN)
java.util.Locale (IN)
java.io.InputStream(java.io.Reader) (IN)
java.io.OutputStream(java.io.Writer) (OUT)
org.springframework.ui.ModelMap (OUT)
などをメソッドの引数に含めることが出来る。
HTTPリクエストに対しバイトストリームをレスポンスしたい場合 OutputStreamを引数に含めておけばそれを使うことが出来るが、content-typeや content-lengthをセットできないためいくつかのケースでは実用的ではないかもしれない。そのような場合、代わりに HttpServletResponseを使うことになると思う。
■おまけ■
Spring 2.5では、プライベートフィールドに @Resourceアノテーションをつけると setterメソッドが無くても beanを autowireしてくれる。(Resourceアノテーションは JEEのものなので、Java SEベースの環境であれば Springの配布に含まれる lib/j2ee/common-annotations.jar をクラスパスに追加すること)
@Resource private DataSource dataSource;
@Resource private PlatformTransactionManager transactionManager;
setterメソッド(フィールドに値を代入するコード)が無いためコンパイラが警告を出すが・・・。
参考: 13.12. Annotation-based controller configuration
web.xmlの設定
Spring 2.0の時と同じで、DispatcherServletをservlet登録し、URIにマッピングする。ただし Spring 2.5の配布では、DispatcherServletは spring.jarに入っておらず spring-webmvc.jarに収録されているため、spring.jarの他に spring-webmvc.jarもプロジェクトに加えること。
WEB-INF直下には、servlet-name要素で指定したサーブレット名の後ろに-servlet.xml を付けた名前で Springのbean定義ファイルを配置する。これも Spring 2.0と同様。
<?xml version="1.0"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-app_2_4.xsd"
version="2.4">
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>hello/*</url-pattern>
</servlet-mapping>
</web-app>
アノテーションで設定をする場合、コントローラは bean要素でただロードさせるだけで良い。
<bean class="com.acme.hello.web.HelloController" />
また、「このパッケージ以下にあるコントローラクラスを全部」のような指定もできる。
xmlns:context="http://www.springframework.org/schema/context"context:component-scan要素は base-packageで指定されたパッケージ以下に存在する @ComponentアノテーションのついたクラスをsingletonなBeanとして自動的に登録してくれる。(後述する @Controllerは @Componentの特殊化)
xsi:schemaLocation="
...
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
..."
:
<context:component-scan base-package="com.acme.hello.web" />
:
コントローラクラスには @Controllerアノテーション(org.springframework.stereotype.Controller)をつけてやる。
@ControllerURIに処理をマッピングするには、@RequestMappingアノテーションを使う。
public class HelloController {
:
}
1種類のURIに1個のコントローラを割り当てる場合はコントローラクラスに、1個のコントローラで様々なURIの処理を行うにはコントローラクラスのpublicメソッドにそれぞれ @ResultMappingアノテーションでURIを指定する。ここでは後者を例にとる。
リクエスト毎にインスタンスの生成される Struts2(aka WebWork)のActionクラスと違い、Spring MVCのコントローラクラスはシングルトンなので、リクエストパラメータやビュー層へ渡す値についてはメソッドの引数を使う。メソッドの引数とリクエストパラメータの対応付けもアノテーションで指定できる。また、引数に Mapがあるとそこにはビューに渡す値のマップとして使える Mapのインスタンスが渡される。
@RequestMapping("/hello.do")
public String hello() throws Exception
{
return "hello.jsp"; // hello.jspへ処理を渡す
}
他にも
public String hello(@RequestParam("name") String name, Map results)
{
results.put("message", "Hello, " + name + "!");
return "hello.jsp";
}
HttpServletRequest(IN)
HttpServletResponse(OUT)
org.springframework.web.context.request.WebRequest (IN)
java.util.Locale (IN)
java.io.InputStream(java.io.Reader) (IN)
java.io.OutputStream(java.io.Writer) (OUT)
org.springframework.ui.ModelMap (OUT)
などをメソッドの引数に含めることが出来る。
HTTPリクエストに対しバイトストリームをレスポンスしたい場合 OutputStreamを引数に含めておけばそれを使うことが出来るが、content-typeや content-lengthをセットできないためいくつかのケースでは実用的ではないかもしれない。そのような場合、代わりに HttpServletResponseを使うことになると思う。
■おまけ■
Spring 2.5では、プライベートフィールドに @Resourceアノテーションをつけると setterメソッドが無くても beanを autowireしてくれる。(Resourceアノテーションは JEEのものなので、Java SEベースの環境であれば Springの配布に含まれる lib/j2ee/common-annotations.jar をクラスパスに追加すること)
@Resource private DataSource dataSource;
@Resource private PlatformTransactionManager transactionManager;
setterメソッド(フィールドに値を代入するコード)が無いためコンパイラが警告を出すが・・・。
ラベル: Spring

0 件のコメント:
コメントを投稿
<< ホーム