1.搭建开发环境
Spring2.5需要的JAR文件:
spring-framework-2.5.6\dist\spring.jar
spring-framework-2.5.6\lib\jakarta-commons\commons-logging.jar
Struts2.2需要的JAR文件
struts-2.2.1.1\lib\commons-fileupload-1.2.1.jar
struts-2.2.1.1\lib\commons-io-1.3.2.jar
struts-2.2.1.1\lib\freemarker-2.3.16.jar
struts-2.2.1.1\lib\javassist-3.7.ga.jar
struts-2.2.1.1\lib\ognl-3.0.jar
struts-2.2.1.1\lib\struts2-core-2.2.1.1.jar
struts-2.2.1.1\lib\xwork-core-2.2.1.1.jar
struts-2.2.1.1\lib\struts2-spring-plugin-2.2.1.1.jar Spring整合Struts2需要的
在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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <!-- 配置Spring监听器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:beans.xml</param-value> </context-param> <!-- 配置Struts2 --> <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>
JSP页面如下:
<%@ page language="java" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Source City</title> </head> <body> <s:form action="distanceAction" method="post"> <table> <tr> <td>Source City</td> <td><s:textfield name="srcCity" /></td> </tr> <tr> <td>Destination City</td> <td><s:textfield name="destCity" /></td> </tr> <tr> <td>Distance</td> <td><font color="red">${distance }</font></td> </tr> <tr> <td colspan="2"><s:submit value="Find" /></td> </tr> </table> </s:form> </body> </html>
2.开发Service
a.Service接口
package com.apress.springrecipes.city; public interface CityService { /** * 计算两个城市的距离 * @param srcCity 出发地 * @param destCity 目的地 * @return 两个城市之间的距离 */ public double findDistance(String srcCity,String destCity); }
b.开发Service的实现类
package com.apress.springrecipes.city; import java.util.Map; public class CityServiceImpl implements CityService { private Map<String, Map<String, Double>> distanceMap; public void setDistanceMap(Map<String, Map<String, Double>> distanceMap) { this.distanceMap = distanceMap; } /** * 计算两个城市的距离 * @param srcCity 出发地 * @param destCity 目的地 * @return 两个城市之间的距离 */ @Override public double findDistance(String srcCity, String destCity) { Map<String, Double> destinationMap = distanceMap.get(srcCity); if (destinationMap == null) { throw new IllegalArgumentException("Source city not found"); } Double distance = destinationMap.get(destCity); if (distance == null) { throw new IllegalArgumentException("Destination city not found"); } return distance; } }
在Spring的配置文件beans.xml中配置service
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="cityService" class="com.apress.springrecipes.city.CityServiceImpl"> <property name="distanceMap"> <map> <entry key="New York"> <map> <entry key="London" value="5574" /> <entry key="BeiJing" value="10974" /> </map> </entry> </map> </property> </bean> </beans>
3.开发Action整合Spring
有两种方法:
第一种:
package com.apress.springrecipes.city.struts2; import javax.servlet.ServletContext; import org.apache.struts2.ServletActionContext; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import com.apress.springrecipes.city.CityService; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; public class DistanceAction extends ActionSupport { private static final long serialVersionUID = 6770573934287194873L; private String srcCity; private String destCity; public String getSrcCity() { return srcCity; } public void setSrcCity(String srcCity) { this.srcCity = srcCity; } public String getDestCity() { return destCity; } public void setDestCity(String destCity) { this.destCity = destCity; } @Override public String execute() throws Exception { //获取ServletContext对象 ServletContext servletContext = ServletActionContext.getServletContext(); /** * 在Web容器中获取Spring容器 * 此方法需要一个ServletContext对象 */ WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext); //取得Service对象 CityService cityService = (CityService) ctx.getBean("cityService"); //调用Service double distance = cityService.findDistance(srcCity, destCity); //存值 ActionContext.getContext().put("distance", distance); return SUCCESS; } }
struts.xml
<struts> <constant name="struts.devMode" value="true" /> <constant name="struts.ui.theme" value="simple" /> <package name="default" namespace="" extends="struts-default"> <action name="distanceAction" class="com.apress.springrecipes.city.struts2.DistanceAction"> <result name="success">/distance.jsp</result> </action> </package> </struts>
这种方法Struts2并没有托管给Spring管理,只是在Action中通过Spring的容器获取Service而已。两者还是相对独立的。觉得还不算Struts与Spring集成吧,或者集成的不彻底吧。(哈,一家之言,欢迎拍转)。
第二种方法:
package com.apress.springrecipes.city.struts2; import com.apress.springrecipes.city.CityService; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; public class DistanceAction2 extends ActionSupport { private static final long serialVersionUID = 6770573934287194873L; //注入Service private CityService cityService; public void setCityService(CityService cityService) { this.cityService = cityService; } private String srcCity; private String destCity; public String getSrcCity() { return srcCity; } public void setSrcCity(String srcCity) { this.srcCity = srcCity; } public String getDestCity() { return destCity; } public void setDestCity(String destCity) { this.destCity = destCity; } @Override public String execute() throws Exception { double distance = cityService.findDistance(srcCity, destCity); // 存值 ActionContext.getContext().put("distance", distance); return SUCCESS; } }
struts.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN" "http://struts.apache.org/dtds/struts-2.1.7.dtd"> <struts> <constant name="struts.devMode" value="true" /> <constant name="struts.ui.theme" value="simple" /> <package name="default" namespace="" extends="struts-default"> <!-- 这里的class="distanceAction2"只是一个“伪类” 真正的实现类在Spring的beans.xml中定义 --> <action name="distanceAction2" class="distanceAction2"> <result name="success">/distance2.jsp</result> </action> </package> </struts>
然后,beans.xml中要加入如下配置:
<!-- 第二种方法 --> <!-- 配置scope="prototype" (推荐) 或者 scope="request" 以保证每次请求都创建一个新的Action实例 --> <bean id="distanceAction2" class="com.apress.springrecipes.city.struts2.DistanceAction2" scope="prototype"> <property name="cityService" ref="cityService" /> </bean>
这次Action的实例由Spring创建管理,而需要的Service组件,则需要提供Service的Setter方法来注入进去来得到Service,即:所有的组件都在Spring中注册了,通通交由Spring管理了。