转载请注明出处:jiq?钦‘s
technical Blog
1 集成Struts:
给web工程集成Struts2比较简单,下载struts2,将所需的jar文件add进去,然后配置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" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>zk_regcenter</display-name> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list> <!-- 请求处理者配置 --> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
然后新建struts.xml文件,配置Action即可:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <constant name="struts.enable.DynamicMethodInvocation" value="false" /> <constant name="struts.devMode" value="false" /> <package name="default" namespace="/" extends="struts-default,json-default"> <action name="Login" class="org.zk.action.LoginAction"> <result name="success">/index.jsp</result> <result name="error">/error.jsp</result> </action> <!-- 配置管理Action --> <action name="InitTreeData" class="org.zk.action.ConfigManageAction" method="InitTreeData"> <result name="success" type="json"> <param name="root">initTreeData</param> </result> </action> <action name="InitTreeChildrenData" class="org.zk.action.ConfigManageAction" method="InitTreeChildrenData"> <result name="success" type="json"> <param name="root">initTreeChildData</param> </result> </action> <action name="DispNodeInfo" class="org.zk.action.ConfigManageAction" method="DisplayNodeInfo"> <result name="success" type="json"> <param name="root">nodeInfo</param> </result> </action> <action name="SaveNodeInfo" class="org.zk.action.ConfigManageAction" method="SaveNodeInfo"> <result name="success" type="json"> <param name="root">configOpResult</param> </result> </action> <action name="CreateNewNode" class="org.zk.action.ConfigManageAction" method="CreateNewNode"> <result name="success" type="json"> <param name="root">configOpResult</param> </result> </action> <action name="DeleteExistNode" class="org.zk.action.ConfigManageAction" method="DeleteExistNode"> <result name="success" type="json"> <param name="root">configOpResult</param> </result> </action> <!-- 服务管理Action --> <action name="InitServiceData" class="org.zk.action.ServiceManageAction" method="InitServiceData"> <result name="success" type="json"> <param name="root">initServiceData</param> </result> </action> <action name="InitServiceIpsData" class="org.zk.action.ServiceManageAction" method="InitServiceIpsData"> <result name="success" type="json"> <param name="root">initServiceIpsData</param> </result> </action> <action name="DisplayServiceInfo" class="org.zk.action.ServiceManageAction" method="DisplayServiceInfo"> <result name="success" type="json"> <param name="root">serviceInfo</param> </result> </action> </package> </struts>
备注:为什么要引入Spring?
主要是利用面向接口编程的这个思想,结合Spring的IoC容器将业务逻辑解耦。
比如Action中要存储一些业务数据,有时候可能存储在数据库中,有时候可能存储在文件。再比如我最近搞的一个分布式注册中心,配置信息可能就不存储在数据库,而是存储在ZooKeeper集群中,所以需要在action中使用访问ZooKeeper的类,甚至我就算访问ZooKeeper,有时候用原生的ZooKeeper对象访问,有时候用Curator来访问ZooKeeper。我们不可能将所有这些访问数据库,或者ZooKeeper集群的对象都在Action中显示New出来,一旦要换一种方式你该如何,改代码?
所以我们在action中只是定义存储数据的接口对象,调用其接口来进行数据存取,然后再Spring的IoC容器中配置具体的实现了接口的数据存取实现类对象,不管使用哪种方式,只需要在配置Action bean的时候,通过修改配置文件,将具体的实现类利用Spring IoC容器的特性,自动注入到Action中即可。即配置了多种类的bean对象,然后根据需要自由组合。
这就是面向接口编程和Spring IOC容器的魅力所在。
2 集成spring:
集成spring进来也不难,下载spring,将其中除去doc和source之外的jar全部add进去,配置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" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>zk_regcenter</display-name> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list> <!-- spring配置 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <error-page> <exception-type>java.lang.Exception</exception-type> <location>/error.jsp</location> </error-page> <!-- 请求处理者配置 --> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
然后配置applicationContext.xml(记得和web.xml一起放在默认的WEB-INF目录下),将action单例交给spring IOC容器管理:
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="ConfigAction" class="org.zk.action.ConfigManageAction" scope="prototype" /> </beans>
注意:关于spring bean中的scope配置
如果scope配置为prototype就表明每次请求Action都会创建一个新的Action实例来响应这个请求,如果要每次请求都共用同一个Action单例来响应请求应该将scope配置为singleton。换句话说如果你希望每次请求action能够保留上一次请求的状态,用singleton,如果希望每次请求action都需要一个新的action,而不想保留上次请求处理的action的状态,就配置为prototype。
单例模式效率高,但是会带来一些线程安全等问题,可能多个客户端请求同一个action实例导致状态不一致等,这个配置成什么模式具体看你的业务。
一般情况下配置为prototype,也有配置为singleton的时候,比如我有一个ZooKeeper连接对象需要注入到多个action中用户访问ZooKeeper,其中只是读写zk集群,不会涉及到有什么信息需要保存,计算是普通应用程序也希望用一个单例模式来获取这个ZooKeeper访问对象,那么这个时候这个zk访问对象就可以配置为singleton,然后注入到action中使用。
然后将之前配置的struts.xml中的action配置中的class属性全部修改为spring Ioc容器中配置的action的bean id即可:
<!-- 配置管理Action --> <action name="InitTreeData" class="ConfigAction" method="InitTreeData"> <result name="success" type="json"> <param name="root">initTreeData</param> </result> </action>
备注:然后启动tomcat服务器,如果启动发现找不到action的异常,是由于没有导入struts2-spring-plugin-2.3.20.jar导致。