2007-12-07

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もプロジェクトに加えること。

<?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>
WEB-INF直下には、servlet-name要素で指定したサーブレット名の後ろに-servlet.xml を付けた名前で Springのbean定義ファイルを配置する。これも Spring 2.0と同様。

アノテーションで設定をする場合、コントローラは bean要素でただロードさせるだけで良い。

<bean class="com.acme.hello.web.HelloController" />

また、「このパッケージ以下にあるコントローラクラスを全部」のような指定もできる。
xmlns:context="http://www.springframework.org/schema/context"
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" />
:
context:component-scan要素は base-packageで指定されたパッケージ以下に存在する @ComponentアノテーションのついたクラスをsingletonなBeanとして自動的に登録してくれる。(後述する @Controllerは @Componentの特殊化)

コントローラクラスには @Controllerアノテーション(org.springframework.stereotype.Controller)をつけてやる。
@Controller
public class HelloController {
:
}
URIに処理をマッピングするには、@RequestMappingアノテーションを使う。
1種類のURIに1個のコントローラを割り当てる場合はコントローラクラスに、1個のコントローラで様々なURIの処理を行うにはコントローラクラスのpublicメソッドにそれぞれ @ResultMappingアノテーションでURIを指定する。ここでは後者を例にとる。

@RequestMapping("/hello.do")
public String hello() throws Exception
{
return "hello.jsp"; // hello.jspへ処理を渡す
}
リクエスト毎にインスタンスの生成される Struts2(aka WebWork)のActionクラスと違い、Spring MVCのコントローラクラスはシングルトンなので、リクエストパラメータやビュー層へ渡す値についてはメソッドの引数を使う。メソッドの引数とリクエストパラメータの対応付けもアノテーションで指定できる。また、引数に Mapがあるとそこにはビューに渡す値のマップとして使える Mapのインスタンスが渡される。

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メソッド(フィールドに値を代入するコード)が無いためコンパイラが警告を出すが・・・。

ラベル:

0 件のコメント:

コメントを投稿

<< ホーム