Spring DM統合Strtus 2(一)
Spring DMとStruts 2の統合を完成するには、主に二つのことを完成します.は、Struts 2をOGi環境に統合する. は、Spring DMとStruts 2を統合し、Struts 2がSpring DMで定義されたBeanを使用することができるようにする. この記事はSpring DMM Web Extederの方式ではなく、Spring DMM WebはプロジェクトをWebコンテナに手動で登録し、しばらくはtomcatとjeyのみをサポートします.
Struts 2はOSI環境に集積されている.
このステップの目的は、Struts 2のbundleに実際にはbundleの下のStrutsプロファイルを読めるようにすることです.Struts 2自体は、classpathの下の3種類のプロファイルを処理しただけです.それぞれstruts-default.xml、struts-plugin.xmlファイルです.コードはorg.apphe.struts.dispatcher.Disppatchにあります.このようなソースコードを探して、prvate void init_を修正します.TraditionalXml Configrations()メソッド
その中のOGiXml ConfigrationProviderのコードは添付ファイルを見て、 主なコードはloadConfigrationFiles方法にあります.
Struts 2はOSI環境に集積されている.
このステップの目的は、Struts 2のbundleに実際にはbundleの下のStrutsプロファイルを読めるようにすることです.Struts 2自体は、classpathの下の3種類のプロファイルを処理しただけです.それぞれstruts-default.xml、struts-plugin.xmlファイルです.コードはorg.apphe.struts.dispatcher.Disppatchにあります.このようなソースコードを探して、prvate void init_を修正します.TraditionalXml Configrations()メソッド
private void init_TraditionalXmlConfigurations() {
String configPaths = initParams.get("config");
if (configPaths == null) {
configPaths = DEFAULT_CONFIGURATION_PATHS;
}
String[] files = configPaths.split("\\s*[,]\\s*");
for (String file : files) {
if (file.endsWith(".xml")) {
if ("xwork.xml".equals(file)) {
configurationManager.addContainerProvider(createXmlConfigurationProvider(file, false));
} else {
configurationManager.addContainerProvider(createStrutsXmlConfigurationProvider(file, false, servletContext));
}
} else {
throw new IllegalArgumentException("Invalid configuration file name");
}
}
//FIXME bundle 。
configurationManager.addContainerProvider(new OSGiXmlConfigurationProvider("struts_osgi.xml",false,servletContext));
}
その中のOGiXml ConfigrationProviderのコードは添付ファイルを見て、 主なコードはloadConfigrationFiles方法にあります.
Bundle[] bundles=Activator.getContext().getBundles();
ByteArrayOutputStream bos=new ByteArrayOutputStream();
for(Bundle bundle:bundles){
try {
// bundle struts.xml
if(bundle.getSymbolicName().equals(Activator.getContext().getBundle().getSymbolicName())) continue;
url=bundle.getEntry(DEFAULT_CONFIG_NAME);
if(url==null) continue;
is=url.openStream();
IOUtils.copy(is, bos);
is=new ByteArrayInputStream(bos.toByteArray());
InputSource in = new InputSource(is);
in.setSystemId(is.toString());
Document doc=DomHelper.parse(in,dtdMappings);
try{
//
addDefaultNamespace(doc,bundle.getHeaders().get(WEB_CONTEXT),HashFile.getHash(bos.toByteArray()),bundle.getBundleId());
}catch(Exception e){
LOG.error(" ", e, new String[]{});
}
docs.add(doc);
} catch (IOException e) {
LOG.error(" ID "+bundle.getBundleId()+" bundle !", e, new String[]{});
}finally{
if(is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bos!=null){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
次にStruts 2を登録するservletです.Equinoxのhttpを採用していますので、HttpServiceで登録します.package com.yinhai.osgi.web.struts2;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import org.apache.log4j.Logger;
import org.apache.struts2.dispatcher.ng.servlet.StrutsServlet;
import org.eclipse.equinox.http.helper.BundleEntryHttpContext;
import org.eclipse.equinox.http.helper.ContextPathServletAdaptor;
import org.eclipse.equinox.jsp.jasper.JspServlet;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleListener;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.SynchronousBundleListener;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.http.HttpContext;
import org.osgi.service.http.HttpService;
import org.osgi.service.http.NamespaceException;
import org.osgi.util.tracker.ServiceTracker;
/**
* struts2 servlet web bundle 。
* @author Dream.Lee
* @version 2013-6-5
*/
public class StrutsController implements BundleListener {
private static Logger logger=Logger.getLogger(StrutsController.class);
public static final String WEB_CONTEXT="Web-Context";
public static final String STATIC_SUBFIX="_res";
private HttpService httpService;
public static final String WEB_CONTENT_PATH = "/WebContent";
public void activate(ComponentContext context) {
registerController("/*.do");
// bundle web
Bundle[] bundles=Activator.getContext().getBundles();
for(Bundle bundle:bundles){
if(bundle.getHeaders().get(WEB_CONTEXT)!=null&&bundle.getState()==Bundle.ACTIVE){
try {
ServiceTracker<HttpService, HttpService> sTracker=new ServiceTracker<HttpService, HttpService>(bundle.getBundleContext(), HttpService.class.getName(), null);
sTracker.open();
HttpService httpService=sTracker.getService();
if(httpService!=null){
httpService.registerResources(bundle.getHeaders().get(WEB_CONTEXT)+STATIC_SUBFIX,WEB_CONTENT_PATH,
null);
// JSP
HttpContext commonContext = new BundleEntryHttpContext(
bundle, WEB_CONTENT_PATH);
Servlet adaptedJspServlet = new ContextPathServletAdaptor(
new JspServlet(bundle,
WEB_CONTENT_PATH), bundle.getHeaders().get(
WEB_CONTEXT));
httpService.registerServlet(
bundle.getHeaders().get(WEB_CONTEXT) + "/*.jsp",
adaptedJspServlet, null, commonContext);
}
// sTracker.close();
} catch (NamespaceException e) {
e.printStackTrace();
} catch (ServletException e) {
e.printStackTrace();
}
}
}
Activator.getContext().addBundleListener(this);
Activator.getContext().addBundleListener(new SynchronousBundleListener() {
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public void bundleChanged(BundleEvent event) {
Bundle bundle=event.getBundle();
if (bundle.getHeaders().get(WEB_CONTEXT) != null) {
switch(event.getType()){
case BundleEvent.STOPPING:
ServiceReference sf=bundle.getBundleContext().getServiceReference(HttpService.class.getName());
HttpService httpService = (HttpService) bundle
.getBundleContext().getService(sf);
try{
httpService.unregister(bundle.getHeaders().get(WEB_CONTEXT)+STATIC_SUBFIX);
logger.info(" "+bundle.getHeaders().get(WEB_CONTEXT));
}catch(Exception e){
logger.info(" :"+bundle.getHeaders().get(WEB_CONTEXT), e);
}finally{
bundle.getBundleContext().ungetService(sf);
}
break;
}
}
}
});
}
public void setHttpService(HttpService httpService) {
this.httpService = httpService;
}
private void registerController(String webcontext) {
try {
StrutsServlet controller = new StrutsServlet();
httpService.registerServlet(webcontext, controller, null, null);
controller.init();
logger.info(" :" + webcontext);
} catch (Exception e) {
logger.error(" :" + webcontext + " ", e);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public void bundleChanged(BundleEvent event) {
Bundle bundle = event.getBundle();
if (bundle.getHeaders().get(WEB_CONTEXT) != null) {
if (event.getType() == BundleEvent.STARTED) {
logger.info(" "
+ bundle.getHeaders().get(WEB_CONTEXT)+STATIC_SUBFIX + ","
+ bundle.getHeaders().get(WEB_CONTEXT)
+ "/*.jsp");
BundleContext context = bundle.getBundleContext();
ServiceReference sf=context.getServiceReference(HttpService.class.getName());
HttpService httpService = (HttpService) bundle
.getBundleContext().getService(sf);
try {
//
httpService.registerResources(bundle.getHeaders().get(WEB_CONTEXT)+STATIC_SUBFIX,
WEB_CONTENT_PATH, null);
// JSP
Servlet adaptedJspServlet = new ContextPathServletAdaptor(
new JspServlet(bundle,
WEB_CONTENT_PATH), bundle
.getHeaders().get(WEB_CONTEXT));
httpService.registerServlet(bundle.getHeaders()
.get(WEB_CONTEXT) + "/*.jsp",
adaptedJspServlet, null, null);
} catch (NamespaceException e) {
e.printStackTrace();
} catch (ServletException e) {
e.printStackTrace();
}
}
}
}
}
このような宣言方式を採用して発表します.構成ファイルは以下の通りです.<?xml version="1.0" encoding="UTF-8"?>
<component name="strutscontroller">
<implementation class="com.yinhai.osgi.web.struts2.StrutsController"/>
<reference name="HttpService" interface="org.osgi.service.http.HttpService" bind="setHttpService" unbind="unsetHttpService" policy="dynamic"/>
</component>