基于felix框架的struts+springDm的web开发

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