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文件夹下,启动进行访问即可。