struts最新本身已经支持felix1.4,但felix1.4版本本身不支持fragment,本文通过struts2.2.1和springDM1.2搭建了基于felix的OSGI的web开发。具体步骤如下:
1、建立基于struts2.2.1,springDm1.2,支持felix的osgi的web工程:
配置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" id="WebApp_ID" version="2.5"> <display-name>webapp2.2.1</display-name> <context-param> <param-name>struts.osgi.clearBundleCache</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>struts.osgi.runLevel</param-name> <param-value>4</param-value> </context-param> <filter> <filter-name>struts2-prepare</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter</filter-class> </filter> <filter> <filter-name>struts2-execute</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2-prepare</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>struts2-execute</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class>org.apache.struts2.osgi.StrutsOsgiListener</listener-class> </listener> <listener> <listener-class>org.apache.struts2.dispatcher.ng.listener.StrutsListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> </listener> <!-- <context-param> <param-name>log4jConfigLocation</param-name> <param-value>/WEB-INF/log4j.properties</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> --> <context-param> <param-name>contextClass</param-name> <param-value>org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext</param-value> </context-param> <context-param> <param-name>contextConfigLocation</param-name> <param-value>osgibundle:/META-INF/spring/*.xml,spring/*.xml</param-value> </context-param> <context-param> <param-name>parentContextKey</param-name> <param-value>parent-context-bean</param-value> </context-param> <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>
web工程中的struts配置文件如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.objectFactory" value="osgi" /> <constant name="struts.objectFactory.delegate" value="springOsgi" /> <!-- <constant name="struts.objectFactory.spring.delegate" value="spring" /> <constant name="struts.convention.result.path" value="/content/"/> <constant name="struts.convention.default.parent.package" value="osgi-default" /> --> </struts>
log4j内容如下:
log4j.rootCategory=DEBUG,stdout,R # Set the level to DEBUG if you want to log all SlideExceptions (some of them aren't errors) log4j.category.org.apache.slide.common.SlideException=FATAL ######################################## log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout # Pattern to output the caller's file name and line number. #log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n #log4j.appender.stdout.layout.ConversionPattern=%4p [%t] %c - %m%n log4j.appender.stdout.layout.ConversionPattern=[%t] %-5p %-20c{2} - %m %n log4j.appender.R=org.apache.log4j.RollingFileAppender log4j.appender.R.File=D:/logger.log log4j.appender.R.ImmediateFlush=true log4j.appender.R.MaxFileSize=100KB # Keep one backup file log4j.appender.R.MaxBackupIndex=1 log4j.appender.R.layout=org.apache.log4j.PatternLayout #log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n #log4j.appender.R.layout.ConversionPattern=%4p [%t] %c - %m%n log4j.appender.R.layout.ConversionPattern=%d{ABSOLUTE} [%t] %-5p %-30c{3} %x - %m %n
2、定义time接口的buddle
package com.example.time; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; public class Activator implements BundleActivator { /* * (non-Javadoc) * * @see * org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext * ) */ public void start(BundleContext context) throws Exception { System.out.println("com.example.time buddle is start!"); // create a tracker and track the log service } /* * (non-Javadoc) * * @see * org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) */ public void stop(BundleContext context) throws Exception { System.out.println("com.example.time buddle is stop!"); } }
package com.example.time.service; public interface TimeService { public String getTime(); public String getTime(String hello); }
配置文件
Manifest-Version: 1.0 Export-Package: com.example.time.service Bundle-Vendor: EXAMPLE Bundle-Version: 1.0.0.201011051048 Bundle-Name: Time Bundle-Activator: com.example.time.Activator Bundle-ManifestVersion: 2 Import-Package: org.osgi.framework;version="1.3.0" Bundle-SymbolicName: com.example.time Bundle-RequiredExecutionEnvironment: JavaSE-1.6
3.定义接口实现的buddle,具体内容如下:
package com.example.time.local; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; public class Activator implements BundleActivator { /* * (non-Javadoc) * * @see * org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext * ) */ public void start(BundleContext bundleContext) throws Exception { System.out.println("com.example.time.local bundle is start"); } /* * (non-Javadoc) * * @see * org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) */ public void stop(BundleContext bundleContext) throws Exception { System.out.println("com.example.time.local bundle is stop"); } } package com.example.time.local.service; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import com.example.time.service.TimeService; public class LocalTimeService implements TimeService { @Override public String getTime() { Calendar calendar = Calendar.getInstance(); Date date = calendar.getTime(); SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("hello"); return "The local time:" + formatter.format(date); } public LocalTimeService() { // TODO Auto-generated constructor stub System.out.println("hello export service."); } @Override public String getTime(String hello) { // TODO Auto-generated method stub return hello + " : " + this.getTime(); } }
配置文件信息
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Local Bundle-SymbolicName: com.example.time.local Bundle-Version: 1.0.0.qualifier Bundle-Activator: com.example.time.local.Activator Bundle-Vendor: EXAMPLE Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Import-Package: com.example.time.service, org.osgi.framework;version="1.3.0"
2个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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="TimeService" class="com.example.time.local.service.LocalTimeService"/> </beans> <?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:osgi="http://www.springframework.org/schema/osgi" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd"> <osgi:service id = "testService" ref="TimeService" interface="com.example.time.service.TimeService"/> </beans>
4、定义struts web bundle工程
package com.example.time.web; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; public class Activator implements BundleActivator { /* * (non-Javadoc) * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) */ public void start(BundleContext bundleContext) throws Exception { System.out.println("com.example.time.web is start"); } /* * (non-Javadoc) * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) */ public void stop(BundleContext bundleContext) throws Exception { System.out.println("com.example.time.web is stop"); } } package com.example.time.web.action; import org.apache.struts2.osgi.interceptor.BundleContextAware; import org.osgi.framework.BundleContext; import com.example.time.service.TimeService; import com.opensymphony.xwork2.ActionSupport; public class TimeAction extends ActionSupport implements BundleContextAware { private BundleContext bundleContext; private String timeMessage; private TimeService timeService; public String execute() { this.timeMessage = this.timeService.getTime(); return "success"; } public String getTimeMessage() { return this.timeMessage; } public void setTimeMessage(String timeMessage) { this.timeMessage = timeMessage; } public TimeService getTimeService() { return this.timeService; } public void setTimeService(TimeService timeService) { this.timeService = timeService; } public void setBundleContext(BundleContext arg0) { this.bundleContext = arg0; } }
applictionContext.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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:osgi="http://www.springframework.org/schema/osgi" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd"> <osgi:reference id="testService" interface="com.example.time.service.TimeService"/> <bean id = "timeAction" class = "com.example.time.web.action.TimeAction" > <property name="timeService" ref ="testService"/> </bean> </beans>
men-info文件如下:
Manifest-Version: 1.0 Export-Package: com.example.time.web;uses:="org.osgi.framework",com.ex ample.time.web.action;uses:="com.example.time.service,com.opensymphon y.xwork2,org.osgi.framework,org.apache.struts2.osgi.interceptor" Private-Package: time,. Struts2-Enabled: true Bundle-ManifestVersion: 2 Bundle-Name: Web Bundle-SymbolicName: com.example.time.web Bundle-Version: 1.0.0.qualifier Bundle-Activator: com.example.time.web.Activator Bundle-Vendor: EXAMPLE Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Import-Package: com.example.time.service, com.opensymphony.xwork2, org.apache.struts2.osgi.interceptor, org.osgi.framework;version="1.3.0"
tim.ftl
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <title>Untitled Document</title> </head> <body> <h1> Hello world,Bundle test.${timeMessage}</h1> </body> </html>
strut.xml配置如下:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="time-example" namespace="/time" extends="osgi-default"> <action name="time" class="timeAction"> <result type = "freemarker">/time/time.ftl</result> </action> </package> </struts>
将3个工程打包,放到web工程的bundle中的3文件夹下,启动进行访问即可。