2 表单验证的流程
在login.jsp网页上,不输入姓名,直接单击submit按钮,会提示“请输入用户名”的信息。
当用户提交LoginForm表单时,请求路径为/login.do,服务器执行表单验证流程如下:
(1)Servlet容器在web.xml文件中寻找<url-pattern>属性为”*.do”的<servlet-mapping>元素:
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
(2)Servlet容器依据以上<servlet-mapping>元素的<servlet-name>属性action,在web.xml文件中寻找匹配的<servlet>元素:
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
(3)Servlet容器把请求转发给以上<servlet>元素指定的ActionServlet,ActionServlet依据用户请求路径”/login.do”,在Struts配置文件中检索path属性为”/login”的<action>元素:
<action-mappings >
<action
attribute="loginForm"
input="/form/login.jsp"
name="loginForm"
path="/login"
scope="request"
type="yan.struts.action.LoginAction">
<set-property property="cancellable" value="true" />
<forward name="login-success" path="/success.jsp" />
</action>
</action-mappings>
(更确切的说,ActionServlet此时检索的是ActionMapping对象,而不是直接访问Struts配置文件中的action元素,因为在ActionServelt初始化的时候,会加载Struts配置文件,把各种配置信息保存在相应的配置类的实例中,例如<action>元素的配置信息存放在ActionMapping对象中).
(4)ActionServlet根据<action>元素的name属性,创建一个LoginForm对象,把客户提交的表单数据传给LoginForm对象,再把LoginForm对象保存在<action>元素的scope属性指定的request范围内。
(5)由于<action>元素的alidate属性为true,ActionServlet调用LoginForm对象的validate()方法执行表单验证。
(6)LoginForm对象的validate()方法返回一个ActionErrors对象,里面包含一个
ActionMessage对象,这个ActionMessage对象中封装了错误消息,消息key为
“login.error.username”,在Resource Bundle中与之值匹配的消息文本为:
login.error.username=请输入用户名
(7) ActionServlet把LoginForm的validate()方法返回的ActionErrors对象保存request范围内,然后根据<action>元素的input属性,把客户请求转发给login.jsp。
(8)login.jsp的<html:errors>标签从request范围内读取ActionErrors对象,再从ActionErrors对象中读取ActionMessage对象,把它包含的错误消息显示在网页上。
3 逻辑验证失败的流程
接下来在login.jsp的HTML表单中输入用户名为admin,然后单击submit按钮,当服务器端相应客户的请求时,验证流程如下:
(1)重复以上(1)------(4)
(2)ActionServlet调用LoginForm对象的validate()方法,这次validate()方法返回的ActionErrors对象中不包含任何ActionMessage对象,表示表单验证成功。
(3)ActionServlet查找loginAction实例是否存在,如果不存在就创建一个实例。然后调用LoginAction的execute()方法
(4)LoginAction的execute()方法先进行逻辑验证,由于没有通过逻辑验证,就创建了一个ActionMessage对象,这个ActionMessage对象封装了错误消息,消息key为
login.error.badusername= 用户名不能为admin
execute()方法把ActionMessage对象保存在ActionMessages对象中,再把ActionMessages对象存放在request范围内。最后返回一个ActionForward对象,该对象包含的请求转发路径为<action>元素的input属性指定的login.jsp。
(5)ActionServlet依据LoginAction返回的ActionForward对象,再把请求转发给login.jsp,
(6)login.jsp的<html:errors>标签从request范围内读取ActionMessages对象,再从ActionMessages对象中读取ActionMessage对象,把它包含的错误消息显示在网页上。
4 逻辑验证成功的流程
(1)重复以上(1)----(3)
(2)LoginAction的execute()方法先执行逻辑验证,这次通过了验证,然后执行相关的业务逻辑,最后调用ActionMapping.findForward()方法,参数为”login-success”:
return mapping.findForward("login-success");
(3)ActionMapping.findForward()方法从<action>元素中寻找name属性为“login-success”的<forward>子元素,然后返回与之对应的ActionForward对象,它代表的请求转发路径为
“/success.jsp”。
(更确切的说,ActionMapping从本身包含的HashMap中查找name属性为“login-success”的ActionForward对象。在ActionServlet初始化时会加载struts配置文件,把<action>元素的配置信息存放在ActionMapping对象中。<action>元素中可以包含多个<forward>子元素,每个<forward>子元素的配置信息存放在一个ActionForward对象中,这些ActionForward对象存放在ActionMapping对象的HashMap中)
(4)LoginAction的execute()方法然后把ActionForward对象返回给ActionServlet,ActionServlet再把客户请求转发给login.jsp
(5)login.jsp的<bean:message>标签从Resource Bundle中读取文本,把它们输出到网页上,最后生成动态网页。