要完成Spring DM与Struts2的集成,主要完成两件事
- 将Struts2集成到OSGi环境中。
- 将Spring DM与Struts2集成,使Struts2可以使用Spring DM中定义的Bean。
此文章采用的方法不是Spring DM Web Extender的方式,由Spring DM Web是将工程手动注册到Web容器中,暂时只支持tomcat与jetty。
Struts2集成到OSGi环境中
这步的目的是让Struts2的bundle可以读到其实bundle下的Struts配置文件,由于Struts2本身只处理了classpath下面的三类配置文件,分别为struts-default.xml、struts-plugin.xml、struts.xml文件,所以首先我们要增加读取bundle下面配置文件的ConfigurationProvider,代码在org.apache.struts2.dispatcher.Dispatcher,将此类的源代码找出来,然后修改private void init_TraditionalXmlConfigurations()方法
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)); }
其中OSGiXmlConfigurationProvider的代码见附件, 主要的代码在loadConfigurationFiles方法中
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(); } } } }
接下来就是注册Struts2的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>
相关推荐
“Struts2相关信息.txt”可能包含了与Struts2相关的其他信息,如最佳实践、性能优化技巧或者框架与其他技术(如Spring、Hibernate)的集成方法。 “附 Struts1应用.txt”虽然不是直接关于Struts2,但可能对比了...
6.3 将Spring与Struts 1.x集成 220 6.3.1 问题 220 6.3.2 解决方案 220 6.3.3 工作原理 220 6.4 将Spring与JSF集成 226 6.4.1 问题 226 6.4.2 解决方案 226 6.4.3 工作原理 227 6.5 将Spring与DWR...
6.3 将Spring与Struts 1.x集成 220 6.3.1 问题 220 6.3.2 解决方案 220 6.3.3 工作原理 220 6.4 将Spring与JSF集成 226 6.4.1 问题 226 6.4.2 解决方案 226 6.4.3 工作原理 227 6.5 将Spring与DWR...
**Spring Dynamic Modules (Spring DM)**是Spring的一个子项目,它将Spring框架与OSGi框架结合起来,使得Spring应用程序能够在OSGi环境下运行。Spring DM利用了Spring的IoC容器和OSGi的模块化能力,为开发者提供了一...
SSH整合指的是将三个开源框架Struts2、Spring3和Hibernate3集成在一起,用于构建高效、稳定的企业级Web应用。这三种框架分别承担着MVC模式中的表现层、业务层和服务层的角色,协同工作以实现数据的持久化、业务逻辑...
SSH,全称是Struts2、Spring和Hibernate的组合,是一种在Java Web开发中常用的开源框架集成。这个"SSH精简包.rar"包含了这三种框架的核心库,旨在提供一个轻量级的解决方案,去除了不常用或者冗余的组件,以提高开发...
**SSH**脚手架是Struts、Spring和Hibernate的集成,它为Web应用提供了一个灵活的开发框架。Struts处理MVC模式中的视图和控制,Spring负责依赖注入和事务管理,Hibernate则作为ORM工具处理数据库交互。 **Spring-DM*...
- **Struts 1.x/Struts 2**: 分别支持 Struts 1 和 Struts 2 框架,包括 XML 和 Tag 提示。 - **Tapestry**: 支持 Tapestry 框架,这是一个结合了 MVC 和模板技术的 Java Web 框架。 - **Vaadin**: 支持 Vaadin 框架...
SSH(Spring、Struts、Hibernate)框架组合是Java后端开发的常用技术栈,而在SSH框架下实现多数据源支持,可以有效地处理来自不同数据库的数据,提高系统的灵活性和可扩展性。本文将详细介绍如何使用Spring 3的动态...
3. **SSH 框架**: SSH 是 Struts、Spring 和 Hibernate 的集成框架,广泛应用于轻量级 Web 应用程序开发。Struts 提供 MVC 架构,Spring 实现了依赖注入(IoC)和面向切面编程(AOP),Hibernate 则是 ORM 工具,...
WebWork是一个开源的Java Web应用框架,主要用于构建企业级的Web应用程序。...此外,了解WebWork的进化历程和它如何与Struts2等其他框架融合也很有帮助,因为这能让你了解框架的发展趋势和技术选择的重要性。
- **OSGi**:为Java平台定义了一个动态模块系统,Equinox 和 SpringDM 是其中两个实现。 - **SOA框架**:如Apache Tuscany,用于构建服务导向架构(SOA)应用。 - **P3:特定领域框架** - **Flex/Sliverlight**:...
- **Struts+Spring框架**:用于构建稳定、灵活的Web应用程序,提供良好的结构和组件。 - **XML与XSL**:XML用于数据交换和存储,XSL实现数据格式转换,可用于构建前后端分离的系统。 - **Flash与XML**:Flash通过...