将特定请求映射到特定Action的相关信息存储在ActionMapping中,ActionServelt将ActionMapping传送到Action类的execute()方法,Action将使用ActionMapping的findForward()方法,此方法返回一个指定名称的ActionForward,这样Action就完成了本地转发。若没有找到具体的ActionForward,就返回一个null.
ActionMapping的方法:
public ExceptionConfig findException(Class type) ,查找异常对象
public ActionForward findForward(String name) 可在映射中动态添加ActionForward:
public String[] findForwards()找到一个Action可以使用的actionForward列表
public ActionForward getInputForward() 得到本action的输入ActionForard.
ActionMapping继承于org.apache.struts.config.ActionConfig
Action类
Action类真正实现应用程序的事务逻辑,它们负责处理请求。在收到请求后,ActionServlet会:
1.为这个请求选择适当的Action
2.如果需要,创建Action的一个实例
3.调用Action的execute()方法
如果ActionServlet不能找到有效的映射,它会调用默认的Action类(在配置文件中定义)。如果找到了ActionServlet将适当的ActionMapping类转发给Action,这个Action使用ActionMapping找到本地转发,然后获得并设置ActionMapping属性。根据servlet的环境和被覆盖的execute ()方法的签名,ActionServlet也会传送ServletRequest对象或HttpServletRequest对象。
所有Action类都扩展org.apache.struts.action.Action类,并且覆盖类中定义的某一个execute ()方法。有两个execute ()方法:
处理非HTTP(一般的)请求:
public ActionForward execute (ActionMapping action,
Acionform form,
ServletRequest request,
ServletResponse response)
throws java.lang.Exception
处理HTTP请求:
public ActionForward execute (ActionMapping action,
Acionform form,
HttpServletRequest request,
HttpServletResponse response)
throws java.lang.Exception
Action类必须以”线程安全”的方式进行编程,因为控制器会令多个同时发生的请求共享同一个实例,相应的,在设计Action类时就需要注意以下几点:
不能使用实例或静态变量存储特定请求的状态信息,它们会在同一个操作中共享跨越请求的全局资源
如果要访问的资源(如JavaBeans和会话变量)在并行访问时需要进行保护,那么访问就要进行同步
Action类的方法
除了execute ()方法外,还有以下方法:
可以获得或设置与请求相关联的区域:
public Locale getLocale(HttpServletRequest request)
public void setLocale(HttpServletRequest request,Locale locale)
为应用程序获得消息资源:
protected MessageResources getResources(HttpServletRequest request)
protected MessageResources getResources(HttpServletRequest request,String key)
检查用户是否点击表单上的”取消”键,如果是,将返回true:
public Boolean isCancelled(HttpServletRequest request)
当应用程序发生错误时,Action类能够使用下面方法存储错误信息:
public void saveErrors(HttpServletRequest request,ActionErrors errors)
public void saveMessages(HttpServletRequest request,ActionMessages messages)
ActionError实例被用来存储错误信息,这个方法在错误关键字下的请求属性列表中存储ActionError对象。通过使用在struts标记库中定义的自定义标记,JSP页能够显示这些错误信息。ActionMessages 用来存储一些提示信息,不是错误,在jsp页面可以使用标记现实这些提示信息。
请求有效性处理,使用令牌可以有效的防止重复提交。
protected String generateToken(HttpServletRequest request) 创建一个令牌.
protected boolean isTokenValid(HttpServletRequest request) 检查令牌是否有效
protected boolean isTokenValid(HttpServletRequest request,Boolean reset) 检查令牌是否有效,并且重置令牌(如果reset 是true)
protected void resetToken(HttpServletRequest request) 重置令牌
protected void saveToken(HttpServletRequest request) 添加令牌
获取数据库连接
protected DataSource getDataSource(HttpServletRequest request)
protected DataSource getDataSource(HttpServletRequest request, String key)
其他的
ActionServlet getServlet() 可以获得本action的配置信息.
DispatchAction类
DispatchAction是Action的子类,主要功能可以实现,动态的方法调用。例如action中有一个方法update(ActionMapping mapping, Actionform form, HttpServletRequest request, HttpServletResponse response), 可以通过 saveSubscription.do?method=update来调用update方法。这个类不需要我们实现其他方法,我们只要实现 XXX(ActionMapping mapping, Actionform form, HttpServletRequest request, HttpServletResponse response)就可以了。
在http://www.chinajavaworld.net/forum/topic.cgi?forum=48&topic=1166&show=150和
http://www.chinajavaworld.net/forum/topic.cgi?forum=48&topic=1129有对DispatchAction和LookupDispatchAction的详细介绍
SwitchAction类
SwitchAction是Action的子类,主要功能是将请求在不同的模块之间转发。对于大的项目很有用。具体看http://www.chinajavaworld.net/forum/topic.cgi?forum=48&topic=1029&show=0
Actionform类
假设用户在应用程序中为每个表单都创建了一个Actionform bean,对于每个在struts-config.xml文件中定义的bean,框架在调用Action类的execute()方法之前会进行以下操作:
在相关联的关键字下,它检查用于适当类的bean实例的用户会话(或请求),如果在会话(或请求)中没有可用的bean,它就会自动创建一个新的bean并添加到用户的会话(或请求)中。至于是在会话还是请求取决于struts-config.xml 中Action 的scope属性。在创建Actionform的时候,系统会将请求中的值,进行相应的类型转换以后对Actionform进行初始化。
对于请求中每个与bean属性名称对应的参数,Action调用相应的设置方法。
当Action execute()被调用时,最新的Actionform bean传送给它,参数值就可以立即使用了。
Actionform类扩展org.apache.struts.action.Actionform类,程序开发人员创建的bean能够包含额外的属性,而且ActionServlet可能使用反射(允许从已加载的对象中回收信息)访问它。
Actionform类提供了另一种处理错误的手段,提供两个方法:
Public ActionErrors validate(ActionMappin mapping, ServletRequest request)
Public ActionErrors validate(ActionMappin mapping, HttpServletRequest request)
你应该在自己的bean里覆盖validate()方法,并在配置文件里设置<action>元素的validate为true。在ActionServlet调用Action类前,它会调用validate(),如果返回的ActionErrors不是null,则Actinform会根据错误关键字将ActionErrors存储在请求属性列表中。
如果返回的不是null,而且长度大于0,则根据错误关键字将实例存储在请求的属性列表中,然后ActionServlet将响应转发到配置文件<action>元素的input属性所指向的目标。
如果需要执行特定的数据有效性检查,最好在Action类中进行这个操作,而不是在Actionform类中进行。
方法reset()可将bean的属性恢复到默认值:
public void reset(ActionMapping mapping,HttpServletRequest request)
public void reset(ActionMapping mapping,ServletRequest request)
典型的ActionFrom bean只有属性的设置与读取方法(getXXX),而没有实现事务逻辑的方法。只有简单的输入检查逻辑,使用的目的是为了存储用户在相关表单中输入的最新数据,以便可以将同一网页进行再生,同时提供一组错误信息,这样就可以让用户修改不正确的输入数据。而真正对数据有效性进行检查的是Action类或适当的事务逻辑bean。
Actionform中属性允许的类型boolean,byte,short,char,int,long,float,double,Boolean,Btye,Short, Character,Integer,Long,Float,Double,String,Date,Time,Timestamp,Object,以及以上类型的数组。
如果Actionform bean 的属性是一个数组则相应的设置和读取方法要做部分修改。对于数组setXXX(…),和getXXX()在jsp页面中意义不大。应该将添加setXXX( int index , …. ) 方法和getXXX ( int index )方法。这两个方法对于jsp页面来说更有意义。jsp中的property应该是XXX[0]。
如果Actionform bean的属性是一个 Map则应该提供方法setXXX( String key , … )和getXXX(String key),使得jsp页面可以访问Map属性。jsp中的properry应该是XXX(keyname)。
通过getXXX(int index),setXXX (int index,…),getXXX(String key),setXXX(String key,…)可以方便的实现重复html输入框。
例如:
public class Fooform extends Actionform {
private String yourName;
public String getYourName() {
return yourName;
}
public void setYourName(String yourName) {
this.yourName = yourName;
}
private final Map values = new HashMap();
public void setvalue(String key, Object value) {
values.put(key, value);
}
public Object getvalue(String key) {
if ( values.containsKey(key)){
return values.get(key);
}else{
return "";
}
}
…
}
Validatorform类
org.apache.struts.validator.Validatorform类继承了Actionform类。使用本类可以方便的实现表单参数的校验。在校验的时候,使用在struts-config.xml中action元素中的name属性,确定要在validation.xml中取得校验规则的依据。
使用本类可以方便的解决同一个form在不同的Action中使用不同的校验规则的问题。在继承了Validatorform的类中不再需要我们去写validate方法。而是由Validatorform中的validate方法通过读取validation.xml中的描述信息来进行数据的校验。使用Validatorform也可以方便的实现在浏览器端实现利用脚本的校验。
Validatorform中的新增加的方法:
int getPage()
java.util.Map getResultvalueMap()
ValidatorResults getValidatorResults()
void setPage(int page)
void setValidatorResults()
使用本类可以大大提高我们的编程效率。
ValidatorActionform类
org.apache.struts.validator.ValidatorActionform类继承了Validatorform类。使用本类可以方便的实现表单参数的校验。在校验的时候,使用在struts-config.xml中action元素中的path属性,确定要在validation.xml中取得校验规则的依据。
DynaActionform类
org.apache.struts.action.DynaActionform类继承了Actionform类。使用本类可以方便的实现动态表单。创建不确定的表单,如果jsp发生了变化只需要修改jsp页面和struts-config.xml文件中的form-bean元素就可以了。我们的程序中完全可以不用手工书写actionform的类了。
DynaActionform中的方法:
boolean contains(String name, String key) 检测name(key)在actionform中是否存在。
Object get(String name) 从actionform中取得name的值。
Object get(String name,int index) 从actionform中取得 name对象的index个值。
Object get(String name,String key)从actionform中取得name对象的key对应的值。
Map getMap() 返回对象中包含的对象属性名列表。
void remove(String name, String key) 删除一个元素。
void set(String name, int index,Object value) 对actionform中的属性进行赋值。
void set(String name,Object value)
void set(String name, Strign key ,Object value)
DynaValidatorform类
org.apache.struts.validator.DynaValidatorform类继承了DynaActionform类。使用本类可以方便的实现表单参数的校验。在校验的时候,使用在struts-config.xml中action元素中的name属性,确定要在validation.xml中取得校验规则的依据。
至于校验,同Validatorform。
DynaValidatorform中的新增加的方法:
int getPage()
java.util.Map getResultvalueMap()
ValidatorResults getValidatorResults()
void setPage(int page)
void setValidatorResults()
DynaValidatorActionform类
org.apache.struts.validator.DynaValidatorActionform类继承了DynaValidatorform类。使用本类可以方便的实现表单参数的校验。在校验的时候,使用在struts-config.xml中action元素中的path属性,确定要在validation.xml中取得校验规则的依据。
至于校验,同Validatorform。
ActionForward类
ActionForward类继承了org.apache.struts.config.ForwardConfig。
ForwardConfig的方法:
String getName() 虚名字
String getPath() 实际路径
boolean getRedirect() 是否重定向
void setName(String name)
void setPath(String path)
void setRedirect(boolean redirect)
ActionForward目的是控制器将Action类的处理结果转发至目的地。
Action类获得ActionForward实例的句柄,然后可用两种方法返回到ActionServlet,
ActionMapping实例被传送到execute()方法,使用actionMapping的findForward(String name)根据名称获取一个全局转发或本地转发。
另一种是调用下面的一个构造器来创建它们自己的一个实例:
public ActionForward()
public ActionForward(String path)
public ActionForward(String path,Boolean redirect)
public ActionForward(String name,String path,Boolean redirect)
public ActionForward(String name,String path,Boolean redirect, boolean contextRelative)
或下面的构造方法(下面是ActionForward的子类)
ForwardingActionForward()
ForwardingActionForward(String path)
RedirectingActionForward()
RedirectingActionForward(String path