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()メソッド
     
     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>