如上定义了formbean,我们将讨论struts的执行过程?
Struts的控制器组件包括ActionServlet类和Action类,其中ActionServlet是struts框架自带的核心控制器类,对应类名为org.apache.struts.action.ActionServlet,所有的请求都先由ActionServlet来处理,然后再由ActionServlet把请求转发给其他组件,Struts框架只允许在一个应用中配置一个ActionServlet类,在应用的生命周期中只创建一个ActionServlet类的一个实例,这个ActionServlet可以响应多个用户请求。
我们在页面中创建一个表单:
<html:form action=”/Hello.do”focus=”name”>//表单请求路径为/hello.do,即表单提交后,生成与当前路径相对的路径./hello.do,focus用于定位光标位置在名为name的文本输入框中。
<html:text property=”name” size=”16” maxlength=”20”/>//创建文本输入框
<html:submit property=”submit” value=”submit”/>//创建按钮
</html:form>
下一步我们根据表单的属性来建立一个表单类,用于完成对表单的数据的绑定与操作。文件名为HelloForm.java:
package hello;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
public final class HelloForm extends ActionForm {//扩展struts的ActionForm类
private String name=null;//绑定表单中的名为name的文本输入框的数据,初值为null
public String getName(){
return(this.name)
}//getName方法
public void setName(String name) {
this.name=name;
}
//下面是Struts的ActionForm自带的两个方法,reset()和validate()方法
public void reset(ActionMapping mapping,HttpServletRequest request){
this.name=null;
}
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request){
ActionErrors errors= new ActionErrors();
If((name=null)||(name.length()<1))
Errors.add(“name”, new ActionMessage(“hello.no.name.error”));
Return errors;
}//end of validate
}//end of class
下一步,我们配置web.xml如下:
<servlet>
<servlet-name>action</servlet-name>//定义servlet的名字
<servlet-class>org,apache.struts.action.ActionServlet</servlet-class>//action对应的类名,因为一个应用中只能有一个ActionServlet,所以只能定义一个servlet-name,但是可以配置多个模块,下面的配置中定义了两个模块,将一个应用的模块分开,有利于工程的分工与维护,下面的两个模块共用一个ActionServlet。但是如果将ActionServlet类扩展,则可以将servlet-name元素定义为其他的名字,但是此时的servlet-class为扩展后的类名。
<init-param>
<param-name>config</param-name>//定义一个默认模块,config是ActionServlet的专属参数名
<param-value>/WEB-INF/struts-config.xml</param-value>//struts配置文件的相对路径
</init-param>
<init-param>
<param-name>config/Module2</param-name>//以config/开头就表示不是默认的模块
<param-value>/WEB-INF/struts-module2.xml</param-value>//与Module2相对应的struts配置文件的相对路径
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>//响应以.do结尾的所有请求,这样前面定义的表单在提交后就在web.xml文件中找到了servlet的name即action.然后根据<init-param>元素中的struts配置文件相对路径读取servlet的配置信息
</servlet-mapping>
下面是struts-config.xml文件的配置:
<struts-config>
<form-beans>
<form-bean name=”HelloForm” type=”hello.HelloForm”/>//配置ActionForm Bean
</form-beans>
<action-mappings>
<action path=”/Hello” //访问action的相对路径,即如果路径为localhost/hello.do,则就调用action
type=”hello.HelloAction”//访问此action,将请求转发给的acton的类名
name=”HelloForm”//用来区别action的属性,此属性的值必须与上面<form-beans>中定义的元素的name属性一致。
scope=”request”//action存在于request范围内
validate=”true”//是否对表单进行验证
input=”/hello.jsp”//如果出错后返回的页面
>
</action>
<forward name=”Sayhello” path=”/hello.jsp”/>
</action-mappings>
</struts-config>
我们可以看到,上面配置实现了与HelloForm的绑定。
然后在HelloAction.java中,我们将表单用下面的代码就可以实例化:
ActionForm form;
String name=(HelloForm)form.getName();//其中,HelloForm即在struts-config.xml文件中<action>元素的name属性值,这样我们就可以访问不同的ActionForm。
总结流程:
l 用户提交表单
l Struts根据表单的请求路径,在web.xml中指定servlet,并根据<init-param>元素读取servlet的配置信息
l ActionServlet或者扩展的ActionServlet接收请求,并根据请求的路径来判断调用哪一个action,即action元素中的path路径,再根据action元素中的type属性,用来指定处理请求的逻辑action(属于控制器部分),再根据其name属性来绑定form-bean,即创建一个HelloForm对象,并把用户提交的表单数据传给ActionForm对象,这个对象保存在scope设置的范围内。
l 如果action的validate属性设置为true,则ActonServlet就调用HelloForm对象的validate()方法,对表单进行验证。
l ActionServlet查找action是否存在,如果不存在就创建一个实例,然后调用HelloAction的execute()方法。
l 通过execute()方法中的逻辑验证后,执行相关的业务逻辑,最后调用ActionMapping.findForward(“SayHello”)方法。其中的参数SayHello与struts-config.xml文件中的action元素的forword属性值对应,则就将请求转发到“hello.jsp”页面,结束。