<span style="font-size: 14px; font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"></span>
需求:
- 在OSGi环境中集成struts2,提供mvc功能
- 将blueprint 与 Struts2集成,使Struts2可以使用blueprint中定义的spring Bean
环境:
1,Equinox OSGi应用嵌入到web container
2,OSGi 4.2 Blueprint Container
思路:
不论是spring mvc还是struts等mvc框架,其最终的实现还是一个servlet或者是一个filter,对http请求进行拦截。所以,根据这一理解,将struts2的StrutsPrepareAndExecuteFilter通过httpService注册即可。同样的思路,也实现了spring mvc的集成。
实现源码:
1,新建一个bundle,名为:org.osgi.mvc.struts2,作为struts2的功能提供bundle,提供给所有需要用到struts2功能的web bundle依赖。
2,新建Struts2Support类:
public class Struts2Support implements ApplicationContextAware,InitializingBean{
public void afterPropertiesSet() throws Exception {
// TODO Auto-generated method stub
try {
< </span>tracker = new Struts2ServiceTracker((FrameWorkApplicationContext) applicationContext, null);
<> </span>tracker.open();
<> </span>} catch (Exception e) {
<> </span>// TODO: handle exception
<> </span>e.printStackTrace();
<> </span>}
}
}
3,新建Struts2ServiceTracker,将StrutsPrepareAndExecuteFilter注册到osgi容器
public class Struts2ServiceTracker extends ServiceTracker
核心代码为:
FilterServletAdaptor adaptor = new FilterServletAdaptor(filter,initparams, adaptedActionsServlet);
httpService.registerServlet(bundleContextPath + "/*.do",adaptor, initparams, commonContext);
this.aliasSet.add(bundleContextPath);</span>
新建OSGiXmlConfigurationProvider类,用于在filter初始化的时候读取struts2的配置文件,核心代码如下:
private List<Document> loadConfigurationFiles(String fileName,
Element includeElement) {
List<Document> docs = new ArrayList<Document>();
/**
* 首先获得strts2 bundle里的公共配置,base-struts
* 再加载所有bundle里的制定目录下,有关struts2的配置文件
* 制定目录为:<span style="font-family: Arial, Helvetica, sans-serif;">configuration/struts</span>
* **/
{
for (Bundle bundle : bundles) {
Enumeration e = bundle.findEntries("configuration/struts","*.xml", true);
List<Document> doc2 = doFind(e, bundle);
docs.addAll(doc2);
}
}
return docs;
}</span>
5,好了,大功告成了,最后在Dispatcher类里增加OSGiXmlConfigurationProvider
//FIXME 增加bundle中读取配置文件的类
configurationManager.addContainerProvider(createOsgiProvider("struts2.xml",true,servletContext,path,bundleName));
6,启动,注册成功,配置文件读取成功。但是,问题来了,怎样找到spring里配置的bean啊?
即:struts2与spring在osgi环境下的集成,新建一个objectFatory,buildbean方法重写一下即可,请看如下代码:
public Object buildBean(String className, Map<String, Object> extraContext,
boolean injectInternal) throws Exception {
// FIXME
if (className.contains("org.apache.struts2")
|| className.contains("com.opensymphony.xwork2")) {
Class clazz = getClassInstance(className);
Object obj = buildBean(clazz, extraContext);
if (injectInternal) {
injectInternalBeans(obj);
}
return obj;
}
try {
Object obj = null;
try {
<span style="white-space:pre"> </span>obj = OSGIUtil.getBundleBean(bundle.getSymbolicName(), className);
} catch (Exception e) {
// TODO: handle exception
continue;
}
if (obj != null) {
return obj;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
7,ok了,整个过程历时两天半,那个纠结啊,从来没用过struts2的人,看struts的源码,跟踪,调试,个人滋味,你懂我懂。
代码并没有贴处全部,如果大家有需要,欢迎私信啊。
使用方法:
1,依赖org.osgi.mvc.struts2
2,注册Struts2Support作为spring bean ,即可启动struts2支持
<bean class="org.osgi.mvc.struts2.Struts2Support"></bean>
3,启动web容器,启动bundle,访问页面。