Spring MVCを使ってOSGi Web Bundleを作成してみたいと思います。とりあえず、いろいろ準備が要りますが…用意したコードを列挙。
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>my.web.bundle</groupId> <artifactId>my-web-bundle</artifactId> <packaging>war</packaging> <version>1.0.0</version> <name>my-web-bundle Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>org.springframework.spring-library</artifactId> <type>libd</type> <version>3.0.0.M3</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>com.springsource.javax.servlet.jsp.jstl</artifactId> <version>1.2.0</version> <scope>provided</scope> </dependency> </dependencies> <!-- <build> <finalName>my-web-bundle</finalName> </build> --> <build> <plugins> <plugin> <artifactId>maven-war-plugin</artifactId> <version>2.1-beta-1</version> <configuration> <packagingExcludes>WEB-INF/lib/**</packagingExcludes> </configuration> </plugin> </plugins> </build> <repositories> <repository> <id>com.springsource.repository.bundle.external</id> <name>SpringSource Enterprise Bundle Repository - External Bundle Releases</name> <url>http://repository.springsource.com/maven/bundles/external</url> </repository> <repository> <id>com.springsource.repository.bundle.milestone</id> <name>SpringSource Enterprise Bundle Repository - SpringSource Bundle Milestones</name> <url>http://repository.springsource.com/maven/bundles/milestone</url> </repository> <repository> <id>com.springsource.repository.libraries.milestone</id> <name>SpringSource Enterprise Bundle Repository - Milestone Library Releases</name> <url>http://repository.springsource.com/maven/libraries/milestone</url> </repository> </repositories> </project>
基本はgreenpages.webのpom.xmlを参考に作っていますが、SpringSourceのリポジトリの場所やSpringのバージョンは、greenpages.parentプロジェクトから引っ張ってきました。リポジトリは、全部コピーしたわけではありませんが、とりあえずこれだけあればコンパイルエラーなどにはならなくなりました。
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <display-name>Archetype Created Web Application</display-name> <context-param> <param-name>contextClass</param-name> <param-value>org.eclipse.virgo.web.dm.ServerOsgiBundleXmlWebApplicationContext</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>mywebbundle</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>mywebbundle</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
MavenのWebアプリケーション用プロジェクトが生成したものから、Servlet APIのバージョンを引き上げSpringのDispatcherServletを追加しています。
/WEB-INF/mywebbundle-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" /> <!-- enable classpath scanning --> <context:component-scan base-package="my.web.bundle" /> <!-- Configures the @Controller programming model --> <mvc:annotation-driven /> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> </beans>
greenpages.webから拝借しつつ、いくつか変更を加えました。
- SpringのXML Schema定義が2.5を向いていたので、3.0に引き上げ
- コンポーネントスキャンするパッケージは、「my.web.bundle」
- ViewをJSPを使用するように変更
- URLのルールにControllerClassNameHandlerMappingクラスを採用
基本的にはgreenpages.webを見ていますが、Spring MVCのサンプルプロジェクトである、以下のソースを併せて読んで設定しています。
https://src.springframework.org/svn/spring-samples/mvc-basic/trunk/
/WEB-INF/applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:osgi="http://www.springframework.org/schema/osgi" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd"> <!-- import a service from OSGi implementing the Directory interface and make available as a bean called directory --> <!-- <osgi:reference id="directory" interface="greenpages.Directory" /> --> </beans>
これはまだするべきことはありません。greenpages.webから持ってきましたが、コメントアウトしたのと、Springのスキーマバージョンが2.5を向いていたので引き上げておきました。
MANIFEST.MF
Manifest-Version: 1.0 Bundle-SymbolicName: my.web.bundle Bundle-Version: 1.0.0 Bundle-Name: My Web Bundle Web-ContextPath: my-web-bundle Import-Library: org.springframework.spring;version="[3.0,3.1)" Import-Bundle: com.springsource.org.apache.taglibs.standard;version="[ 1.1.2,1.3)" Import-Package: org.eclipse.virgo.web.dm;version="[2.0.0,3.0.0)", org.springframework.beans.factory.annotation;version="[3.0,3.1)", org.springframework.core.io;version="[3.0,3.1)", org.springframework.stereotype;version="[3.0,3.1)", org.springframework.web.bind.annotation;version="[3.0,3.1)", org.springframework.web.context;version="[3.0,3.1)", org.springframework.web.servlet;version="[3.0,3.1)", org.springframework.web.servlet.mvc.annotation;version="[3.0,3.1)"
Import-Packageは、正直Springのものはどれが必要/不要なのかよくわかりません…。greenpages.webのMANIFEST.MFから持ってきつつ、FreeMaker系のライブラリは削りました。JSTLの依存関係が書いてあるのは、ちょっと遊んでいたからです。
Controllerのサンプル
package my.web.bundle; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller // @RequestMapping("/hello") public class HelloController { private int count; @RequestMapping("/index") public String index() { return "index"; } }
URLのルールにControllerClassNameHandlerMappingクラスを利用したので、ControllerにRequestMappingアノテーションを付けなくても「/hello」でアクセスされるようになっています。メソッドをひとつ定義してあり、「/hello/index」でアクセスされると「WEB-INF/jsp/index.jsp」を見に行くようになっています。
<html> <body> <h2>Hello Spring MVC</h2> </body> </html>
何の変哲もない、ただのJSPです。
あと、src/main/resourcesは不要だったので削除しました。
ここまでやったら、STSでVirgo Web Serverを起動して以下のURLにアクセス。
http://localhost:8080/my-web-bundle/hello/index
とりあえず、動作しましたよっと。