4.web
接下来是这次demo的另一个bundle.而且是个拥有spring-mvc能力的web-bundle(WAB).先来看一下结构
首先来看一下web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 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>Search Web Module</display-name> <servlet> <servlet-name>search</servlet-name> <servlet-class>org.phantom.web.virgo.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextClass</param-name> <param-value>org.eclipse.virgo.web.dm.ServerOsgiBundleXmlWebApplicationContext</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>search</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
在这个demo中,我们使用的是Spring-MVC,所以,这里加入Spring-MVC支持.这里用到了一个自定义扩展类org.phantom.web.virgo.servlet.DispatcherServlet。说明一下这个类的作用。在OSGI中,每个bundle都是独立的,它拥有独立的ClassLoad,独立的Spring ApplicationContext.但是我们要通过spring从一个bundle中获取另一个bundle的服务,即我们需要这些applicationContext互相认识.怎么做到呢?virgo对这事做了支持.它提供了一个类org.eclipse.virgo.web.dm.ServerOsgiBundleXmlWebApplicationContext.这个类就相当于一个OSGI全局的applicationContext.我们这里就是要将这个类注入到Spring-MVC的DispatcherServlet中.这里通过扩展默认的DispatcherServlet来达到目的
public class DispatcherServlet extends org.springframework.web.servlet.DispatcherServlet{ @Override public void init(ServletConfig config) throws ServletException { String contextClass = config.getInitParameter("contextClass"); if (contextClass != null) { try { setContextClass(Class.forName(contextClass)); } catch (ClassNotFoundException e) { throw new ServletException(String.format("Context class %s not found", contextClass), e); } } super.init(config); } }然后来看一下OSGI描述.
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: search web module Bundle-SymbolicName: org.phantom.demo.web Bundle-Version: 1.0.0.SNAPSHOT Import-Template: org.springframework.*;version="[3.0.5,4)" Import-Package: org.springframework.context.config;version="[3.0.5,4)", org.springframework.web.servlet.config;version="[3.0.5,4)" Excluded-Imports: org.phantom.demo.web Snap-Host: org.phantom.demo.host;version="1.0.0.SNAPSHOT" Snap-ContextPath: /search这里要介绍Snap-ContextPath:/search.前文已经介绍过Host-Snap,这一句配置就是配置当前bundle的请求路径,即第二级路径.还有一句Snap-Host:org.org.phantom.demo.host.这句配置将当前snap挂载到了某个host上.于是,根据前文的介绍,当进入到/demo后,SnapHostFilter开始工作,拿到请求的第二级/search,分发到当前bundle. 接下来的配置就是Spring-MVC的配置了.在WEB-INF/创建与DispatcherServlet同名的search-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" xmlns:util="http://www.springframework.org/schema/utils" xmlns:osgi="http://www.springframework.org/schema/osgi" xsi:schemaLocation="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/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi-1.2.xsd"> <context:component-scan base-package="org.phantom.demo.web" /> <mvc:annotation-driven/> <mvc:resources location="/" mapping="*.html"/> <mvc:resources location="/resources/" mapping="/resources/**" /> <osgi:reference id="pictureSearch" interface="org.phantom.demo.api.SearchHandler" bean-name="pictureSearch"/> </beans>一句句解释一下.第一句,打开包扫描,将Controller加入到Spring管理中
<context:component-scan base-package="org.phantom.demo.web" />