/**
作者:Willpower
来源:Rifoo Technology(http://www.rifoo.com)
时间:2006-01-15
备注:转载请保留以上声明
**/
今天,请大家跟我一起看看在Spring中如何使用Struts。其实Struts是一个标准的MVC框架,我们要配置一个中心分发器(dispatcher),这个分发器会将请求发送给控制器,控制器响应action中的form调用相关后台方法完成转发页面。
首先,我们来配置Struts,需要做到两点:在web.xml中配置中心分发器,在struts-config.xml中配置Struts控制器。
Example 3-1. web.xml
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
"http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<web-app>
<display-name>RentABike</display-name>
<description>
Renting bikes for fun and profit.
</description>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/rentABikeApp-servlet.xml
</param-value>
</context-param>
<servlet>
<servlet-name>SpringContext</servlet-name>
<servlet-class>
org.springframework.web.context.ContextLoaderServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>RentABike</servlet-name>
<servlet-class>
org.apache.struts.action.ActionServlet
</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>validate</param-name>
<param-value>true</param-value>12
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>RentABike</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>
start.html
</welcome-file>
</welcome-file-list>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.util.Log4jConfigListener
</listener-class>
</listener>
<taglib>
<taglib-uri>/spring</taglib-uri>
<taglib-location>/WEB-INF/spring.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>http://java.sun.com/jstl/core</taglib-uri>
<taglib-location>/WEB-INF/c.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/struts</taglib-uri>
<taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
</taglib>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
</web-app>
如果你以前对Struts很熟悉,那么这里其实没有什么新的东西。我们配置了两个servlet(代码中蓝色高亮的部分),一个用来加载Spring上下文,一个用来加载Struts。<load-on-startup>指定了它们加载的顺序,我们从代码中可以看到目前配置的是先加载Spring,在加载Struts。这里,我们首先加载Spring的原因是这里Struts要依赖Spring创建的RentABike对象,该对象在Struts加载时会用到。下面的紫色部分是jsp需要用到的标签库。我们也配置了servlet-mapping来将所有后缀名为.do的请求都提交到Struts的ActionServlet(代码中红色部分)。
接下来,我们配置action和actionform的映射信息。
Example 3-2. struts-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
<form-beans>
<form-bean name="EditBikeForm"
type="com.springbook.forms.EditBikeForm"/>
</form-beans>
<action-mappings>
<action path="/bikes"
type="org.apache.struts.actions.ForwardAction"
parameter="/bikes.jsp"/>
<action path="/editBike"
type="org.apache.struts.actions.ForwardAction"
parameter="/editBike.jsp"/>
<action path="/submitBike"
type="com.springbook.actions.SubmitBikeAction"
name="EditBikeForm"
scope="request"
validate="true"
input="/editBike.jsp">
<display-name>Submit Bike</display-name>
<forward name="success" path="/bikes.jsp"/>
<forward name="failure" path="/editBike.jsp"/>
</action>
</action-mappings>
</struts-config>
这里定义了actionform bean和action的相关映射信息,这里定义了EditBikeForm用来保存山地车编辑页面的属性。SubmitBikeAction用来处理山地车编辑页面所提交后的表单。
以下是RentABike接口的实现类ArrayListRentABike.java的代码,它相当于一个facade,用作向action隐藏后台数据层的具体操作:
Example 3-3. ArrayListRentABike.java
public class ArrayListRentABike implements RentABike {
private String storeName;
final List bikes = new ArrayList( );
public void saveBike(Bike bike) {
if(bikes.contains(bike)) bikes.remove(bike);
bikes.add(bike);
}
public void deleteBike(Bike bike) {
bikes.remove(bike);
}
public ArrayListRentABike( ) {
initBikes( );
}
public ArrayListRentABike (String storeName) {
this.storeName = storeName;
initBikes( );
}
private void initBikes( ) {
bikes.add(new Bike(1, "Shimano",
"Roadmaster", 20, "11111", 15, "Fair"));
bikes.add(new Bike(2, "Cannondale",
"F2000 XTR", 18, "22222",12, "Excellent"));
bikes.add(new Bike(3, "Trek",
"6000", 19, "33333", 12.4, "Fair"));
}
public String toString( ) {
return "com.springbook.ArrayListRentABike: " + storeName;
}
public String getStoreName( ) {
return storeName;
}
public void setStoreName(String storeName) {
this.storeName = storeName;
}
public List getBikes( ) {
return bikes;
}
public Bike getBike(String serialNo) {
Iterator iter = bikes.iterator( );
while(iter.hasNext( )) {
Bike bike = (Bike)iter.next( );
if(serialNo.equals(bike.getSerialNo( ))) return bike;
}
return null;
}
public Bike getBike(int bikeId) {
if(bikeId > bikes.size( )) return null;
return (Bike)bikes.get(bikeId);
}
//etc...
}
每个action有可能会调用这个facade去和后台数据进行操作。我们编写一个BaseAction,它继承Struts的Action类,负责从Spring上下文中去获得RentABike的一个对象实例(依赖注入思想)。
Example 3-4. BaseAction.java
public abstract class BaseAction extends Action {
private RentABike rentABike;
public void setServlet(ActionServlet actionServlet) {
super.setServlet(actionServlet);
ServletContext servletContext = actionServlet.getServletContext( );
WebApplicationContext wac =
WebApplicationContextUtils.
getRequiredWebApplicationContext(servletContext);
this.rentABike = (RentABike) wac.getBean("RentABike");
}
protected RentABIke getRentABike( ) {
return rentABike;
}
// 放置其他相关的实用方法在后面。。。
}
还记得我们已经在Spring加载的上下文文件rentaBike-Servlet.xml中定义过rentaBike这个bean吧,我们可以在未来可能会更改这个facade类而实现不同的后台操作,这样不用修改代码,实现了依赖注入。
Example 3-5. rentaBike-Servlet.xml
<beans>
<bean id="rentaBike" class="com.springbook.ArrayListRentABike">
<property name="storeName"><value>Bruce's Bikes</value></property>
</bean>
<!-- etc. -->
</beans>
然后我们所有的action都继承这个BaseAction,这样我们都可以实现Spring的依赖注入了。
Example 3-6. SubmitBikeAction.java
public class SubmitBikeAction extends BaseAction {
public SubmitBikeAction( ) {
super( );
}
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws java.lang.Exception {
EditBikeForm editBikeForm = (EditBikeForm) form;
Bike bike = new Bike( );
bike.setManufacturer(editBikeForm.getManufacturer( ));
bike.setModel(editBikeForm.getModel( ));
bike.setFrame(editBikeForm.getFrame( ));
bike.setSerialNo(editBikeForm.getSerialNo( ));
bike.setWeight(editBikeForm.getWeight( ));
try {
//调用facade实现数据的保存
this.rentABike.saveBike(bike);
return mapping.findForward("success");
} catch (Exception ex) {
return mapping.findForward("failure");
}
}
}
接着,我们使用Struts标签来实现EditBike.jsp页面的编写:
Example 3-7. EditBike.jsp
<%@ page import="com.springbook.*"%>
<%@ include file="include.jsp" %>
<%@ taglib prefix="spring" uri="/spring" %>
<%@ taglib uri="/WEB-INF/struts-html-el.tld" prefix="html-el" %>
<html>
<head>
<title>
Edit Bike
</title>
</head>
<body>
<h1>Edit Bike</h1>
<form method="POST">
<table border="1" cellspacing="2" cellpadding="2">
<tr>
<td align="right">Manufacturer:</td>
<td>
<html-el:text property="manufacturer" size="25"
maxlength="50" styleClass="textBox" tabindex="1" />
</td>
</tr>
<tr>
<td align="right">Model:</td>
<td>
<html-el:text property="model" size="25"
maxlength="50" styleClass="textBox" tabindex="1" />
</td>
</tr>
<tr>
<td align="right">Frame:</td>
<td>
<html-el:text property="frame" size="25"
maxlength="50" styleClass="textBox" tabindex="1" />
</td>
</tr>
<tr>
<td align="right">Serial Number:</td>
<td>
<html-el:text property="serialNo" size="25"
maxlength="50" styleClass="textBox" tabindex="1" />
</td>
</tr>
<tr>
<td align="right">Weight:</td>
<td>
<html-el:text property="weight" size="25"
maxlength="50" styleClass="textBox" tabindex="1" />
</td>
</tr>
<tr>
<td align="right">Status:</td>
<td>
<html-el:text property="status" size="25"
maxlength="50" styleClass="textBox" tabindex="1" />
</td>
</tr>
</table>
<html-el:submit styleClass="normal">
Submit Bike
</html-el:submit>
</form>
</body>
</html>
这个文件没什么特别的,都是标准的Struts标签。这里书中用的是struts-html-el标签而不是原始的struts-html标签,它只是可以将JSTL表达式用作Struts标签的属性值。如果你愿意,你仍旧可以使用原始的struts-html标签或其他的标签库。大家注意一下红色部分:为什么这里没有写form提交的action却还能成功提交呢?是因为我们在前面已经将这个editBike.jsp指向了EditBikeForm。
最后,我们来看看传递到action中的EditBikeForm是如何写的:
Example 3-8. EditBikeForm.java
public class EditBikeForm extends ActionForm {
private String manufacturer;
private String model;
private int frame;
private String serialNo;
private double weight;
private String status;
public void reset(ActionMapping mapping, HttpServletRequest request) {
manufacturer = null;
model = null;
frame = 0;
serialNo = null;
weight = 0.0;
status = null;
}
public ActionErrors validate(
ActionMapping mapping,
HttpServletRequest request) {
ActionErrors errors = new ActionErrors( );
String mappingName = mapping.getPath( );
if (mappingName.equalsIgnoreCase("/SubmitBike")) {
if (manufacturer == null
|| manufacturer.trim( ).length( ) == 0) {
errors.add(
"bike",
new ActionError("error.manufacturer.required));
}
if (model == null
|| model.trim( ).length( ) == 0) {
errors.add(
"bike",
new ActionError("error.mo del.required"));
}
}
return errors;
}
public EditBikeForm( ) {
super( );
}
public void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer;
}
public String getManufacturer( ) {
return manufacturer;
}
public void setModel(String model) {
this.model = model;
}
public String getModel( ) {
return model;
}
public void setFrame(int frame) {
this.frame = frame;
}
public int getFrame( ) {
return frame;
}
public void setSerialNo(String serialNo) {
this.serialNo = serialNo;
}
public String setSerialNo( ) {
return serialNo;
}
public void setWeight(Double weight) {
this.weight = weight;
}
public Double getWeight( ) {
return weight;
}
public void setStatus(String status) {
this.status = status;
}
public String getStatus( ) {
return status;
}
}
现在,所有编码已完成,我们接下来写一个简单的测试程序来测试form中的validate方法。
Example 3-9. StrutsTest.java
public void testBikeValidation( ) throws Exception {
//创建一个ActionMapping
ActionMapping mapping = new ActionMapping( );
mapping.setPath("/SubmitBike");
//创建一个EditBikeForm
EditBikeForm ebf = new EditBikeForm( );
ebf.setManufacturer("a manufacturer");
ebf.setModel("a model");
ActionErrors errors = ebf.validate(mapping, null);
assertEquals(0, errors.size( ));
ebf = new EditBikeForm( );
ebf.setManufacturer("a manufacturer");
ebf.setModel("");
//调用EditBikeForm中的validate方法
errors = ebf.validate(mapping, null);
assertEquals(1, errors.size( ));
}
要学习更多复杂的Actions和ActionMappings,大家可以参考这篇文章:
http://www.onjava.com/pub/a/onjava/2004/09/22/test-struts.html
下图是一个Struts应用程序流程图:

在本篇学习中,我们看到,在应用中Spring初始化对象并以属性的形式注入依赖。
作者:Willpower
来源:Rifoo Technology(http://www.rifoo.com)
时间:2006-01-15
备注:转载请保留以上声明
**/
今天,请大家跟我一起看看在Spring中如何使用Struts。其实Struts是一个标准的MVC框架,我们要配置一个中心分发器(dispatcher),这个分发器会将请求发送给控制器,控制器响应action中的form调用相关后台方法完成转发页面。
首先,我们来配置Struts,需要做到两点:在web.xml中配置中心分发器,在struts-config.xml中配置Struts控制器。
Example 3-1. web.xml
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
"http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<web-app>
<display-name>RentABike</display-name>
<description>
Renting bikes for fun and profit.
</description>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/rentABikeApp-servlet.xml
</param-value>
</context-param>
<servlet>
<servlet-name>SpringContext</servlet-name>
<servlet-class>
org.springframework.web.context.ContextLoaderServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>RentABike</servlet-name>
<servlet-class>
org.apache.struts.action.ActionServlet
</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>validate</param-name>
<param-value>true</param-value>12
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>RentABike</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>
start.html
</welcome-file>
</welcome-file-list>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.util.Log4jConfigListener
</listener-class>
</listener>
<taglib>
<taglib-uri>/spring</taglib-uri>
<taglib-location>/WEB-INF/spring.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>http://java.sun.com/jstl/core</taglib-uri>
<taglib-location>/WEB-INF/c.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/struts</taglib-uri>
<taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
</taglib>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
</web-app>
如果你以前对Struts很熟悉,那么这里其实没有什么新的东西。我们配置了两个servlet(代码中蓝色高亮的部分),一个用来加载Spring上下文,一个用来加载Struts。<load-on-startup>指定了它们加载的顺序,我们从代码中可以看到目前配置的是先加载Spring,在加载Struts。这里,我们首先加载Spring的原因是这里Struts要依赖Spring创建的RentABike对象,该对象在Struts加载时会用到。下面的紫色部分是jsp需要用到的标签库。我们也配置了servlet-mapping来将所有后缀名为.do的请求都提交到Struts的ActionServlet(代码中红色部分)。
接下来,我们配置action和actionform的映射信息。
Example 3-2. struts-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
<form-beans>
<form-bean name="EditBikeForm"
type="com.springbook.forms.EditBikeForm"/>
</form-beans>
<action-mappings>
<action path="/bikes"
type="org.apache.struts.actions.ForwardAction"
parameter="/bikes.jsp"/>
<action path="/editBike"
type="org.apache.struts.actions.ForwardAction"
parameter="/editBike.jsp"/>
<action path="/submitBike"
type="com.springbook.actions.SubmitBikeAction"
name="EditBikeForm"
scope="request"
validate="true"
input="/editBike.jsp">
<display-name>Submit Bike</display-name>
<forward name="success" path="/bikes.jsp"/>
<forward name="failure" path="/editBike.jsp"/>
</action>
</action-mappings>
</struts-config>
这里定义了actionform bean和action的相关映射信息,这里定义了EditBikeForm用来保存山地车编辑页面的属性。SubmitBikeAction用来处理山地车编辑页面所提交后的表单。
以下是RentABike接口的实现类ArrayListRentABike.java的代码,它相当于一个facade,用作向action隐藏后台数据层的具体操作:
Example 3-3. ArrayListRentABike.java
public class ArrayListRentABike implements RentABike {
private String storeName;
final List bikes = new ArrayList( );
public void saveBike(Bike bike) {
if(bikes.contains(bike)) bikes.remove(bike);
bikes.add(bike);
}
public void deleteBike(Bike bike) {
bikes.remove(bike);
}
public ArrayListRentABike( ) {
initBikes( );
}
public ArrayListRentABike (String storeName) {
this.storeName = storeName;
initBikes( );
}
private void initBikes( ) {
bikes.add(new Bike(1, "Shimano",
"Roadmaster", 20, "11111", 15, "Fair"));
bikes.add(new Bike(2, "Cannondale",
"F2000 XTR", 18, "22222",12, "Excellent"));
bikes.add(new Bike(3, "Trek",
"6000", 19, "33333", 12.4, "Fair"));
}
public String toString( ) {
return "com.springbook.ArrayListRentABike: " + storeName;
}
public String getStoreName( ) {
return storeName;
}
public void setStoreName(String storeName) {
this.storeName = storeName;
}
public List getBikes( ) {
return bikes;
}
public Bike getBike(String serialNo) {
Iterator iter = bikes.iterator( );
while(iter.hasNext( )) {
Bike bike = (Bike)iter.next( );
if(serialNo.equals(bike.getSerialNo( ))) return bike;
}
return null;
}
public Bike getBike(int bikeId) {
if(bikeId > bikes.size( )) return null;
return (Bike)bikes.get(bikeId);
}
//etc...
}
每个action有可能会调用这个facade去和后台数据进行操作。我们编写一个BaseAction,它继承Struts的Action类,负责从Spring上下文中去获得RentABike的一个对象实例(依赖注入思想)。
Example 3-4. BaseAction.java
public abstract class BaseAction extends Action {
private RentABike rentABike;
public void setServlet(ActionServlet actionServlet) {
super.setServlet(actionServlet);
ServletContext servletContext = actionServlet.getServletContext( );
WebApplicationContext wac =
WebApplicationContextUtils.
getRequiredWebApplicationContext(servletContext);
this.rentABike = (RentABike) wac.getBean("RentABike");
}
protected RentABIke getRentABike( ) {
return rentABike;
}
// 放置其他相关的实用方法在后面。。。
}
还记得我们已经在Spring加载的上下文文件rentaBike-Servlet.xml中定义过rentaBike这个bean吧,我们可以在未来可能会更改这个facade类而实现不同的后台操作,这样不用修改代码,实现了依赖注入。
Example 3-5. rentaBike-Servlet.xml
<beans>
<bean id="rentaBike" class="com.springbook.ArrayListRentABike">
<property name="storeName"><value>Bruce's Bikes</value></property>
</bean>
<!-- etc. -->
</beans>
然后我们所有的action都继承这个BaseAction,这样我们都可以实现Spring的依赖注入了。
Example 3-6. SubmitBikeAction.java
public class SubmitBikeAction extends BaseAction {
public SubmitBikeAction( ) {
super( );
}
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws java.lang.Exception {
EditBikeForm editBikeForm = (EditBikeForm) form;
Bike bike = new Bike( );
bike.setManufacturer(editBikeForm.getManufacturer( ));
bike.setModel(editBikeForm.getModel( ));
bike.setFrame(editBikeForm.getFrame( ));
bike.setSerialNo(editBikeForm.getSerialNo( ));
bike.setWeight(editBikeForm.getWeight( ));
try {
//调用facade实现数据的保存
this.rentABike.saveBike(bike);
return mapping.findForward("success");
} catch (Exception ex) {
return mapping.findForward("failure");
}
}
}
接着,我们使用Struts标签来实现EditBike.jsp页面的编写:
Example 3-7. EditBike.jsp
<%@ page import="com.springbook.*"%>
<%@ include file="include.jsp" %>
<%@ taglib prefix="spring" uri="/spring" %>
<%@ taglib uri="/WEB-INF/struts-html-el.tld" prefix="html-el" %>
<html>
<head>
<title>
Edit Bike
</title>
</head>
<body>
<h1>Edit Bike</h1>
<form method="POST">
<table border="1" cellspacing="2" cellpadding="2">
<tr>
<td align="right">Manufacturer:</td>
<td>
<html-el:text property="manufacturer" size="25"
maxlength="50" styleClass="textBox" tabindex="1" />
</td>
</tr>
<tr>
<td align="right">Model:</td>
<td>
<html-el:text property="model" size="25"
maxlength="50" styleClass="textBox" tabindex="1" />
</td>
</tr>
<tr>
<td align="right">Frame:</td>
<td>
<html-el:text property="frame" size="25"
maxlength="50" styleClass="textBox" tabindex="1" />
</td>
</tr>
<tr>
<td align="right">Serial Number:</td>
<td>
<html-el:text property="serialNo" size="25"
maxlength="50" styleClass="textBox" tabindex="1" />
</td>
</tr>
<tr>
<td align="right">Weight:</td>
<td>
<html-el:text property="weight" size="25"
maxlength="50" styleClass="textBox" tabindex="1" />
</td>
</tr>
<tr>
<td align="right">Status:</td>
<td>
<html-el:text property="status" size="25"
maxlength="50" styleClass="textBox" tabindex="1" />
</td>
</tr>
</table>
<html-el:submit styleClass="normal">
Submit Bike
</html-el:submit>
</form>
</body>
</html>
这个文件没什么特别的,都是标准的Struts标签。这里书中用的是struts-html-el标签而不是原始的struts-html标签,它只是可以将JSTL表达式用作Struts标签的属性值。如果你愿意,你仍旧可以使用原始的struts-html标签或其他的标签库。大家注意一下红色部分:为什么这里没有写form提交的action却还能成功提交呢?是因为我们在前面已经将这个editBike.jsp指向了EditBikeForm。
最后,我们来看看传递到action中的EditBikeForm是如何写的:
Example 3-8. EditBikeForm.java
public class EditBikeForm extends ActionForm {
private String manufacturer;
private String model;
private int frame;
private String serialNo;
private double weight;
private String status;
public void reset(ActionMapping mapping, HttpServletRequest request) {
manufacturer = null;
model = null;
frame = 0;
serialNo = null;
weight = 0.0;
status = null;
}
public ActionErrors validate(
ActionMapping mapping,
HttpServletRequest request) {
ActionErrors errors = new ActionErrors( );
String mappingName = mapping.getPath( );
if (mappingName.equalsIgnoreCase("/SubmitBike")) {
if (manufacturer == null
|| manufacturer.trim( ).length( ) == 0) {
errors.add(
"bike",
new ActionError("error.manufacturer.required));
}
if (model == null
|| model.trim( ).length( ) == 0) {
errors.add(
"bike",
new ActionError("error.mo del.required"));
}
}
return errors;
}
public EditBikeForm( ) {
super( );
}
public void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer;
}
public String getManufacturer( ) {
return manufacturer;
}
public void setModel(String model) {
this.model = model;
}
public String getModel( ) {
return model;
}
public void setFrame(int frame) {
this.frame = frame;
}
public int getFrame( ) {
return frame;
}
public void setSerialNo(String serialNo) {
this.serialNo = serialNo;
}
public String setSerialNo( ) {
return serialNo;
}
public void setWeight(Double weight) {
this.weight = weight;
}
public Double getWeight( ) {
return weight;
}
public void setStatus(String status) {
this.status = status;
}
public String getStatus( ) {
return status;
}
}
现在,所有编码已完成,我们接下来写一个简单的测试程序来测试form中的validate方法。
Example 3-9. StrutsTest.java
public void testBikeValidation( ) throws Exception {
//创建一个ActionMapping
ActionMapping mapping = new ActionMapping( );
mapping.setPath("/SubmitBike");
//创建一个EditBikeForm
EditBikeForm ebf = new EditBikeForm( );
ebf.setManufacturer("a manufacturer");
ebf.setModel("a model");
ActionErrors errors = ebf.validate(mapping, null);
assertEquals(0, errors.size( ));
ebf = new EditBikeForm( );
ebf.setManufacturer("a manufacturer");
ebf.setModel("");
//调用EditBikeForm中的validate方法
errors = ebf.validate(mapping, null);
assertEquals(1, errors.size( ));
}
要学习更多复杂的Actions和ActionMappings,大家可以参考这篇文章:
http://www.onjava.com/pub/a/onjava/2004/09/22/test-struts.html
下图是一个Struts应用程序流程图:

在本篇学习中,我们看到,在应用中Spring初始化对象并以属性的形式注入依赖。