Virgo与Maven整合开发环境搭建(四)

来源:互联网 发布:编写windows应用程序 编辑:程序博客网 时间:2024/05/21 16:12

  4.web

                     接下来是这次demo的另一个bundle.而且是个拥有spring-mvc能力的web-bundle(WAB).先来看一下结构

                       首先来看一下web.xml

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app  
  3.         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.         xmlns="http://java.sun.com/xml/ns/javaee"  
  5.         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  
  6.         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  
  7.         version="2.5">  
  8.   
  9.     <display-name>Search Web Module</display-name>  
  10.   
  11.     <servlet>  
  12.         <servlet-name>search</servlet-name>  
  13.         <servlet-class>org.phantom.web.virgo.servlet.DispatcherServlet</servlet-class>  
  14.         <init-param>  
  15.             <param-name>contextClass</param-name>  
  16.             <param-value>org.eclipse.virgo.web.dm.ServerOsgiBundleXmlWebApplicationContext</param-value>  
  17.         </init-param>  
  18.     </servlet>  
  19.   
  20.     <servlet-mapping>  
  21.         <servlet-name>search</servlet-name>  
  22.         <url-pattern>/*</url-pattern>  
  23.     </servlet-mapping>  
  24. </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来达到目的

Java代码  收藏代码
  1. public class DispatcherServlet extends org.springframework.web.servlet.DispatcherServlet{  
  2.     @Override  
  3.     public void init(ServletConfig config) throws ServletException {  
  4.         String contextClass = config.getInitParameter("contextClass");  
  5.         if (contextClass != null) {  
  6.             try {  
  7.                 setContextClass(Class.forName(contextClass));  
  8.             } catch (ClassNotFoundException e) {  
  9.                 throw new ServletException(String.format("Context class %s not found", contextClass), e);  
  10.             }  
  11.         }  
  12.         super.init(config);  
  13.     }  
  14. }  
                    然后来看一下OSGI描述.
Xml代码  收藏代码
  1. Manifest-Version: 1.0  
  2. Bundle-ManifestVersion: 2  
  3. Bundle-Name: search web module  
  4. Bundle-SymbolicName: org.phantom.demo.web  
  5. Bundle-Version: 1.0.0.SNAPSHOT  
  6. Import-Template: org.springframework.*;version="[3.0.5,4)"  
  7. Import-Package: org.springframework.context.config;version="[3.0.5,4)",  
  8.  org.springframework.web.servlet.config;version="[3.0.5,4)"  
  9. Excluded-Imports: org.phantom.demo.web  
  10. Snap-Host: org.phantom.demo.host;version="1.0.0.SNAPSHOT"  
  11. 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即可
Java代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xmlns:context="http://www.springframework.org/schema/context"  
  5.     xmlns:mvc="http://www.springframework.org/schema/mvc"  
  6.     xmlns:util="http://www.springframework.org/schema/utils"  
  7.     xmlns:osgi="http://www.springframework.org/schema/osgi"  
  8.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd   
  9.         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd  
  10.         http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd  
  11.         http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd  
  12.         http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi-1.2.xsd">  
  13.   
  14.     <context:component-scan base-package="org.phantom.demo.web" />  
  15.     <mvc:annotation-driven/>  
  16.       
  17.     <mvc:resources location="/" mapping="*.html"/>  
  18.     <mvc:resources location="/resources/" mapping="/resources/**" />  
  19.   
  20.     <osgi:reference id="pictureSearch" interface="org.phantom.demo.api.SearchHandler" bean-name="pictureSearch"/>  
  21.  </beans>   
  22.    
                     一句句解释一下.第一句,打开包扫描,将Controller加入到Spring管理中
Java代码  收藏代码
  1. <context:component-scan base-package="org.phantom.demo.web" />  

                     接下来打开mvc的支持.将一些Spring-MVC默认的View、Convertor加入进来。

Java代码  收藏代码
  1. <mvc:annotation-driven/>  

                     后面两句,是对一些静态资源放行的配置,因为我们servlet的拦截模式是/*,所以,静态资源直接放行

Java代码  收藏代码
  1. <mvc:resources location="/" mapping="*.html"/>  
  2. <mvc:resources location="/resources/" mapping="/resources/**" />  

                      这句就是通过Spring-DM获取一个OSGI服务的配置.这里我们只获取图片搜索的实现,MP3的我们留在后续章节,用来说明OSGI的动态性如何体现.

Java代码  收藏代码
  1. <osgi:reference id="pictureSearch" interface="org.phantom.demo.api.SearchHandler" bean-name="pictureSearch"/>  

                       同样,我们与普通OSGI进行一下对比.在普通OSGI中,想要或者一个服务如何编写

Java代码  收藏代码
  1. try {  
  2.     SearchHandler handler = null;  
  3.     ServiceReference<SearchHandler>[] srs = (ServiceReference<SearchHandler>[]) bundleContext.getServiceReferences(SearchHandler.class.getName(),"(bean-name='picutreSearch')");  
  4.     if(srs!=null && srs.length>0)  
  5.         handler = bundleContext.getService(srs[0]);  
  6.       
  7. catch (InvalidSyntaxException e) {  
  8.     e.printStackTrace();  
  9. }  

                     最后来看一下Controller如何编写

Java代码  收藏代码
  1. package org.phantom.demo.web;  
  2.   
  3. import java.util.List;  
  4.   
  5. import javax.annotation.Resource;  
  6.   
  7. import org.phantom.demo.api.SearchBean;  
  8. import org.phantom.demo.api.SearchHandler;  
  9. import org.springframework.http.HttpStatus;  
  10. import org.springframework.http.ResponseEntity;  
  11. import org.springframework.stereotype.Controller;  
  12. import org.springframework.web.bind.annotation.RequestMapping;  
  13. import org.springframework.web.bind.annotation.RequestMethod;  
  14.   
  15. @Controller  
  16. @RequestMapping("/_s")  
  17. public class SearchController {  
  18.   
  19.     @Resource  
  20.     private SearchHandler handler = null;  
  21.   
  22.     @RequestMapping(method = RequestMethod.GET)  
  23.     public ResponseEntity<List<? extends SearchBean>> doSearch(String key) {  
  24.         List<? extends SearchBean> list = handler.doSearch(key);  
  25.         return new ResponseEntity<List<? extends SearchBean>>(list, HttpStatus.OK);  
  26.     }  
  27. }  

                     在Controller中,将获取到的服务注入进来.

Java代码  收藏代码
  1. @Resource  
  2. e SearchHandler handler = null;  

                      ok,然后编写一个很简单的页面.点击按钮发送请求页面上发送一个get请求到Controller,Controller调用service完成整个流程.

Java代码  收藏代码
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  2. <html>  
  3. <head>  
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  5. <script type="text/javascript" src="../resources/jquery-1.6.min.js"></script>  
  6. <script type="text/javascript">  
  7. $(function(){  
  8. $(":button").click(function(){  
  9.     $.ajax({  
  10.         url:'_s',  
  11.         type:'get',  
  12.         data:{key:$(":text").val()},  
  13.         success:function(result){  
  14.             alert(result);  
  15.         }  
  16.     });  
  17. });  
  18. });  
  19. </script>  
  20. </head>  
  21. <body>  
  22. <input/><input type="button" value="search"/>  
  23. </body>  
  24. </html>  

                     所有bundle开发完后,按照依赖关系,依次执行mvn install安装到本地maven仓库.之前已经配置了maven仓库与virgo关联.所以这种开发流程基本是:开发完—install—启动virgo.

                     然后到${virgo_home}/pickup/新建一个plan,即一次部署计划.

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <plan name="com.faben.demo.plan" version="1.0.0.SNAPSHOT" scoped="false" atomic="false"  
  3.         xmlns="http://www.eclipse.org/virgo/schema/plan"  
  4.                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  5.                 xsi:schemaLocation="  
  6.                         http://www.eclipse.org/virgo/schema/plan   
  7.                         http://www.eclipse.org/virgo/schema/plan/eclipse-virgo-plan.xsd">  
  8.   
  9.         <artifact type="bundle" name="org.phantom.demo.host" version="1.0.0.SNAPSHOT"/>  
  10.         <artifact type="bundle" name="org.phantom.demo.web" version="1.0.0.SNAPSHOT"/>  
  11.         <artifact type="bundle" name="org.phantom.demo.search.picture" version="1.0.0.SNAPSHOT"/>  
  12. </plan>  

                      部署计划中只需要写实现包和web包,被依赖的包比如api不用写,Virgo会根据MANIFEST.MF中的依赖定义,在maven库中找到api并加载.

                     做完这些后,启动virgo,访问http://localhost:8080/demo/search/index.html.

                  点击按钮,通过firebug查看请求和返回的数据

 

0 0
原创粉丝点击