Eclipse发布了最新的Virgo Tomccat Server。VTS是一个应用服务器与OSGi紧密结合并且可以开发bundles形式的Spring web apps应用,他们同样拥有OSGi和Spring的特性。真是太好了,所以我想尝试下。但是很多人和我一样没有接触过VTS的开发工作。VTS的入门有些困难, 网上有些新手文档但是大部分需要有Spring DM Server的相关开发经验,所以我决定记录我的入门经验帮助从未用过Spring和VTS的新手。如果你了解OSGi和知道怎么开发OSGI的Bundles并且了解相关的开发知识,那么你可以直接看后面的部分使用Spring和OSGi的特性开发第一个应用。
这个教程将告诉大家环境的配置并且在最后开发一个HelloWorld的应用。我将在没有安装任何工具的情况下从头包括环境的配置一步一步的讲解, 这部分涵盖安装Eclipse,Virgo Tomcat Server和安装Eclipse的开发插件. 你需要对Eclipse有些简单的认识,这样能帮助你了解这部分的内容,但对于开发app不是特别重要, 如果你了解它,在之前的工作中用过,那么你几分钟就能将它安装,所以在这里我就不花篇幅进行详细介绍了。.
安装完后我会开发一个Hello World的应用跑在VTS上,这将作为一个引导告诉大家怎么开发这样的应用,这个例子是Spring开发中非常基础的入门例子,因为我们不需要任何之前的相关经验。另外你会首先知道怎么安装开发工具和使用它。
让我们开始安装工具, 下面会列出你需要的:
• VirgoTomcat Server
• Eclipse
• TheSpringSource Tool Suite Eclipse plugin
首先需要获得Virgo Tomcat Server. http://www.eclipse.org/virgo/download/。解压缩到任意目录, 记住路径稍后会用到,我解压到 /Users/xiaxiayoyo/Personal/Development/virgo-tomcat-server-3.0.2.RELEASE
下面安装开发工具,如果你还没有安装之前提到的Eclipse,到http://www.eclipse.org下载最新版的Eclipse IDE for Java EE,应为这个版本包含所有Web开发中需要的插件。 Eclipse不需要安装,你只需要解压到任意目录就可以了, 当你第一次运行Eclipse,它将要求你选择一个workspace location。 后面你所有的工程文件将保存在这个目录下,你可以使用任意目录,建议使用空目录这样会使你后面不会出什么问题。
接下来安装SpringSource Tool Suite(STS)插件。
SpringSourceTool Suite组件和依赖将从更新站点安装到基于3.6和3.7版本的Eclipse。
1. 安装只有在下面必要条件都满足才能成功: Eclipse版本要求:Eclipse 3.6 或者 Eclipse 3.7 WTP版本要求:Eclipse WTP 3.2 或者更高版本
2. 在Eclipse Update Manager中取消所有更新站点:
2.1 打开Preferences -> Install/Update -> AvailableUpdate Sites in Eclipse
2.2 全选所有站点先点击Enable这是Enable按钮会变成Disable再次点击
2.3 点击“OK”关闭preferences窗口并且保存设置
3. 配置STS更新站点:
3.1 下载下面对应版本的更新站点书签文件
• Eclipse3.6: http://dist.springsource.com/release/TOOLS/composite/e3.6/bookmarks.xml
• Eclipse3.7: http://dist.springsource.com/release/TOOLS/composite/e3.7/bookmarks.xml
3.2 打开Preferences -> Install/Update -> AvailableUpdate Sites in Eclipse
3.3 点击“Import...” 按钮选择刚才下载的bookmarks.xml. 点击“Open” 完成导入.
3.4 验证列表中是否有加入的新站点,如果成功关闭 preference窗口
4. 安装 4.1 通过Help -> Install New Software ...打开update manager
4.2 在“Workwith” 下拉菜单中选择名称为“SpringSourceUpdate Site for Eclipse 3.6” 或 “SpringSource Update Site for Eclipse 3.7”的更新站点
确定选择上图勾选的组件,并且按照上面的安装现象进行安装。
点击Next根据提示一步一步到Finish安装结束。
接下来安装SpringSource DM Server Tools插件,经过我的安装官方给出1.1.1和2.0.0都无法正常安装,只能安装snapshots版,通过官方给出的在线更新地址,安装步骤和上面的一样,按照下图的选项安装。
接下来在Eclipse中设置VTS,打开Eclipse的preferences 找到Server -> Runtime Environments。 点击右边的Add…-按钮,选择SpringSource ->SpringSource dm Server (Runtime) v2.1. 确定勾选上下面的“Create a new local server” . 点击Next, 你被要求输入服务器名称(可以随意) 然后需要选择上面你解压VTS的目录。所以在我这里我输入/Users/xiaxiayoyo/Personal/Development/virgo-tomcat-server-3.0.2.RELEASE。
最后一步我们会尝试将它启动起来。打开“Servers”视图如果不在你的工作区,可通过菜单打开Window -> Show View-> Other… -> Server -> Servers。选择刚才配置的服务点击“Start” (白色三角绿色背景) 或者右键菜单选择"Start". 当状态变为Started, 使用浏览器访问http://localhost:8080. 你将看到服务器的初始页. 你可以通过连接打开控制台并且输入默认密码(用户名:admin,密码:springsource)。
环境配置就结束了. 在下面我们将开发一个hello world应用
应用将由2个bundles组成:The app will consist of two bundles:一个bundle将对外公开一个服务,第二个bundle将包含一个web应用使用第一个bundle的服务来产生一个欢迎页面。
在大多数情况下更好的办法是把服务的接口单独放在一个bundle里面,这样可以避免依赖更新的问题。本教程我们不那么做。为了创建一个bundle,我们需要在Eclipse中先创建一个工程,选择 File -> New -> Project…-> EclipseRT 并且创建一个BundleProject。 取名为HelloProvider.在BundleContent页, 选择Module Type is “None”. 工程创建完后,右键选择工程在菜单中选择Properties->TargetedRuntimes确定选择上面在Eclipse中创建的VTS, 创一个生命服务接口的接口文件,在这里我创建的是com.xiaxiayoyo.helloprovider.HelloProvider这个接口只有一个方法:
- publicString getGreeting()
接下来创建一个实现类;com.xiaxiayoyo.helloprovider.impl.HelloProviderImpl. 实现定义的接口如下:
- public String getGreeting() {
- return "Hello World!";
- }
在标准的OSGi系统里, 我们应该创建一个类BundleActivator,它会实例化服务的实现类和注册它。但在这里我们使用VirgoTomcat Server,我们不必在这么干了,Spring会帮我们干这件事,不过你仍然可以自己来处理,而且一样正常工作,这样是为了将其他项目轻松的迁移到VirgoTomcat server中。
接下来是使用Spring的注册配置来注册OSGi服务, 在你bundle工程的META-INF目录里创建一个新目录"spring",创建一个文件"osgi-context.xml"。在文件里我们定义一个bean将它注册为一个OSGi的服务,如下面文件
- <?xml version="1.0" encoding="UTF-8"?>
- <beansxmlnsbeansxmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:osgi="http://www.springframework.org/schema/osgi"
- xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/osgihttp://www.springframework.org/schema/osgi/spring-osgi.xsd">
- <osgi:serviceinterfaceosgi:serviceinterface="com.xiaxiayoyo.helloprovider.HelloProvider">
- <beanclassbeanclass="com.xiaxiayoyo.helloprovider.impl.HelloProviderImpl" />
- </osgi:service>
- </beans>
你可以看到我们将之前接口的实现类注册为服务。启动这个bundle,VTS将实例化服务实现类HelloProviderImpl并且把它注册为接口HelloProvider的服务,所以其他bundle可以使用这个服务。
下面,要让它们能这么做我们还需要导出这个接口。 打开MANIFEST.MF文件,到runtime页,在“exported packages”中添加com.xiaxiayoyo.helloprovider包, 不要导出实现类的包。
现在我们需要开发一个web工程通过服务来展示欢迎页面。接下来创建一个Dynamic Web Project这里我叫做GreeterUI,Target runtime选择VTS,Configuration选择VTS,如下图:
点击下一步 ,在Default output folder里面将输出路径改为WebContent/WEB-INF/classes,这里的WebContent为在下个页面设置的Content Directory,两个参数一定要确保一直,如下图:
点击下一步,这里的Context Root无关紧要因为在Bundle里面上下文路径在MANIFEST.MF里面配置但是还是建议两个地方一致。如下图:
点击Finish完成。
接下来还需要几步来配置下工程右键工程选择Properties,确定Targeted Runtimes为之前创建的VTS,另外由于这个Web Project的开发需要HelloProvider工程提供的服务,所以在这里需要在Project References里勾选HelloProvider工程。当前这个工程是标准的Web工程,我们需要将它加入Spring Project的特性,我们需要再次右键工程->Spring Tools->Add OSGiBundle Project Nature,并且选择EnableBundle Classpath Container。
工程创建完成后,导入必要的依赖包。使用manifest编辑器打开manifest文件(META-INF->MANIFEST.MF),选择Dependencies页添加依赖项。配置完后如下:
- Manifest-Version:1.0
- Module-Type:Web
- Bundle-SymbolicName:GreetUI
- Bundle-Version:1.0.0
- Bundle-Name:GreetUI
- Bundle-ManifestVersion:2
- Web-ContextPath:greeter
- Import-Package:com.xiaxiayoyo.helloprovider,
- javax.servlet;version="[3.0.0,3.0.0]",
- javax.servlet.http;version="[3.0.0,3.0.0]",
- javax.servlet.jsp.el;version="[2.2.0,2.2.0]",
- javax.servlet.jsp.jstl.core;version="[1.2.0.v20110728,1.2.0.v20110728]",
- org.eclipse.virgo.web.dm;version="[3.0.2.RELEASE,3.0.2.RELEASE]"
- Import-Bundle:com.springsource.org.apache.taglibs.standard;version="[1.1.2.v20110517,1.1.2.v20110517]"
- Import-Library:org.springframework.spring;version="[3.0.5.RELEASE,3.0.5.RELEASE]"
- Bundle-ClassPath:/WEB-INF/classes/
注意一定要设置Classpath,不然会响应404错误。
接下来创建Web应用的控制器,创建一个 class叫 com.xiaxiayoyo.greeterui.GreetingsController ,代码如下:
- @Controller
- public class GreetingsController {
- @RequestMapping(value= "/greeting", method = { RequestMethod.GET,RequestMethod.POST})
- public ModelAndView greeting(HttpServletRequest request) {
- ModelAndViewmv = new ModelAndView();
- mv.addObject("greeting",provider.getGreeting());
- mv.setViewName("greeting");
- returnmv;
- }
- @Autowired
- private HelloProvider provider;
provider会被Virgo Tomcat Server注入之前注册的OSGi服务HelloProvider,The setter will be used by the DM server to set thereference to the HelloProvider service which we have registerd in the OSGiservice registry before. 方法greeting在用户发起请求的时候会被spring调用。这个例子的逻辑比较简单,只是从HelloProvider中拿到欢迎信息然后把信息放入ModelAndView内,ViewName是用来渲染页面的JSP文件名。
接下来需要配置来告诉Spring来为控制器装配OSGi服务,Spring会先查找HelloProvider然后将引用注入到GreetingsController,你需要告诉Spring那些服务是必须的,那么需要,创建一个context-osgi.xml,内容如下:
- <?xmlversionxmlversion="1.0"encoding="UTF-8"?>
- <beansxmlnsbeansxmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:osgi="http://www.springframework.org/schema/osgi"
- xmlns:context="http://www.springframework.org/schema/context"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/osgi
- http://www.springframework.org/schema/osgi/spring-osgi.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context.xsd">
- <osgi:referenceidosgi:referenceid="helloProvider"
- interface="com.xiaxiayoyo.helloprovider.HelloProvider"/>
- </beans>
接下来需要在Web.xml里加入Spring MVC相关的配置,如下:
- <?xmlversionxmlversion="1.0" encoding="UTF-8"?>
- <web-appxmlns:xsiweb-appxmlns: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/javaeehttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
- id="WebApp_ID"version="2.5">
- <display-name>GreetUI</display-name>
- <context-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>
- /WEB-INF/osgi-context.xml
- </param-value>
- </context-param>
- <context-param>
- <param-name>contextClass</param-name>
- <param-value>
- org.eclipse.virgo.web.dm.ServerOsgiBundleXmlWebApplicationContext
- </param-value>
- </context-param>
- <servlet>
- <servlet-name>springDispather</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>springDispather</servlet-name>
- <url-pattern>*.do</url-pattern>
- </servlet-mapping>
- <listener>
- <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
- </listener>
- <welcome-file-list>
- <welcome-file>index.html</welcome-file>
- <welcome-file>index.htm</welcome-file>
- <welcome-file>index.jsp</welcome-file>
- <welcome-file>default.html</welcome-file>
- <welcome-file>default.htm</welcome-file>
- <welcome-file>default.jsp</welcome-file>
- </welcome-file-list>
- </web-app>
DispatcherServlet是Spring MVC中负责转发的,所以我们需要告诉它怎么处理请求,我们在相同的目录下面再创建一个配置文件,配置文件名称的前缀和ServletName一样,springDispather-servlet.xml,内容如下:
- <?xmlversionxmlversion="1.0" encoding="UTF-8"?>
- <beansxmlnsbeansxmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:osgi="http://www.springframework.org/schema/osgi"
- xmlns:context="http://www.springframework.org/schema/context"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/osgi
- http://www.springframework.org/schema/osgi/spring-osgi.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context.xsd">
- <context:component-scanbase-packagecontext:component-scanbase-package="com.xiaxiayoyo.greeterui"/>
- <beanidbeanid="viewResolver"
- class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <propertynamepropertyname="prefix"value="/WEB-INF/jsp/" />
- <propertynamepropertyname="suffix" value=".jsp" />
- </bean>
- </beans>
最后一步, 我们需要一个JSP来渲染我们的欢迎页面. 创建目录/WEB-INF/jsp创建greeting.jsp.
内容如下:
- <%@ page contentType="text/html;charset=UTF-8"language="java" %>
- <%@ taglib prefix="c"uri="http://java.sun.com/jsp/jstl/core" %>
- <html>
- <head>
- <title>Hello!</title>
- </head>
- <body>
- <c:out value="${greeting}"/>
- </body>
- </html>
开发就结束了,剩下的是部署。打开Server视图,右键VTS选择 “Add and Remove Projects…” 添加GreeterUI和HelloProvider两个工程. 当你启动服务器你会看到下面类似的日志输出:
- [2012-04-2215:13:31.078] start-signalling-5 <WE0000I> Starting web bundle 'GreetUI' version '1.0.0' with context path'/greeter'.
- [2012-04-2215:13:31.505] start-signalling-5 <WE0001I> Started web bundle 'GreetUI' version '1.0.0' with context path'/greeter'.
- [2012-04-2215:13:31.507] start-signalling-5 <DE0005I> Started bundle 'GreetUI' version '1.0.0
这个时候打开游览器访问http://localhost:8080/greeter/greeting.do,并且你会看到HelloProvder接口的返回内容。
参考文档: