10.2.2 常用的用户输入验证实现方式
10.2.1中虽然实现了用户登陆功能的,用户输入验证。但是这种方式却很少被使用。本节中介绍实际应用中较为常见的编码方式。代码实现进需要修改
Action类,其余文件的内容无需修改。
代码10-1中登陆案例代码编写中将用户输入验证的代码实现放到execute方法中,这种方法虽然容易被读者理解。但是从代码设计角度来看存在execute方法过于臃肿、不利于代码的重用等问题。更为常见的代码实现方式,则是重写ActionSupport类中的validate方法,在该方法中完成用户输入验证。具体代码如下所示:
packagecom.study.erp.action;
importcom.opensymphony.xwork2.ActionSupport;
public class LoginAction extendsActionSupport{
private String username;
private String password;
//
此处省略属性对应的
get
和
set
方法
….
@Override
public void validate() {
if(username == null || username.trim().equals("")){
addFieldError("username", "用户名不能为空.");
}
if(password == null || password.trim().equals("")){
addFieldError("password", "密码不能为空.");
}else if(password.length()<6 || password.length()>12){
addFieldError("password", "密码长度应在6到12位之间.");
}
}
public String execute(){
return "success";
}
}
代码10-4用户登陆功能LoginAction
比较上述10-4代码和10-1代码读者可以发现,10-4的内容更加简洁。当进行用户输入验证时,该验证代码编写到validate方法。该方法中如果发现用户输入错误时,将错误信息添加到框架FieldError中即可。在进行完所有的用户输入验证后,无需用户编码实现页面的跳转。框架会验证用户输入验证是否正确,如果正确会继续执行execute方法,如果错误会跳转到该Action对应的名为input的结果视图中。
本节案例中的代码实现,是Struts框架下基于编码方式实现用户输入验证所提倡的方式。读者在编写时常见的错误是没有在配置文件中配置名为input的结果视图,其配置文件的代码为:<result name="input">/xxx.jsp</result>。
10.2.3 多方法Action的用户输入验证实现方式
在学习第二章
Action的编写和配置时,我们已经了解到
Struts2的
Action类中可以包含多个方法,每个方法用来完成不同的逻辑操作。例如,我们可以利用同一个
Action来完成一组逻辑相关的操作:用户登陆、用户注册、用户信息修改和用户信息删除。代码实现时需要在一个
Action类中需要包括
4个方法,但是对于这
4个方法来说用户输入校验的规则也是不同的,如果再使用
10.2.2所讲的
validate方法来实现用户输入验证,很难实现预期的效果。
Struts2框架对于这类情况也提供了相应的解决方案。当
Action中包括多个逻辑操作方法时,为完成用户输入验证
Action类的编码须实现
Validateable接口(
ActionSupport类已经实现了
Validateable接口)并编写
validateXxx方法,
Xxx即对应
Action逻辑操作方法的名字。
Struts2框架利用了反射机制在对应的逻辑操作方法执行之前调用相应的
validateXxx方法。
为了让读者更容易读懂本节中的代码,本案例中仅实现了用户注册和用户登陆功能的用户输入校验。用户登陆的用户输入验证规则不变,用户注册功能的用户输入验证规则包括:用户名不能为空、密码不能为空、密码长度必须在6到12位之间、年龄的输入范围必须在0-100之间,邮箱必须包括@字符。
用户登陆功能图示与图10-1,10-2,10-3一致,以下为用户注册功能截图:
(1)
当在页面上只输入年龄-11,邮箱为11时
图10-3 用户注册功验证错误1
(2)
当在页面上输入用户名为11,密码为11,年龄为-11,邮箱为11时:
图10-4 用户注册功验证错误2
(3)
当在页面上输入用户名为唐琳,密码为
123456,年龄为
33,邮箱为
tanglin@dlut.edu.cn时:
图10-5 用户注册功验证成功
以下为【用户登陆功能】、【用户注册功能】实现的代码结构:
图10-6 用户登陆、用户注册功验证代码结构
编写该功能时用户需要编写和创建的文件:
文件名
|
说明
|
备注
|
Login.jsp
|
用户登陆页面
|
视图
|
LoginSuccess.jsp
|
用户登陆成功页面
|
视图
|
Regist.jsp
|
用户注册页面
|
视图
|
RegistSuccess.jsp
|
用户注册成功页面
|
视图
|
UserAction
|
Action类
|
控制器
|
struts.xml
|
Struts2框架的配置文件
|
配置文件
|
web.xml
|
项目的部署描述文件
|
配置文件
|
由于篇幅的关系,以下仅列出UserAction类,Regist.jsp和struts.xml文件的部分代码。其它代码参考光盘中Unit10文件夹下03的项目代码。
UserAction类包含两个逻辑,因此包含了两个逻辑方法分别是
login和
regist。
login方法用于实现用户登陆功能,对应的用户输入校验方法为
validateLogin方法;
regist方法用于实现用户注册功能,对应的用户输入校验方法为
validateRegist方法。具体代码如下所示:
packagecom.study.erp.action;
importcom.opensymphony.xwork2.ActionSupport;
public class UserActionextends ActionSupport{
private String username;
private String password;
private int age;
private String email;
//
此处省略属性对应的
get
和
set
方法
….
//
用户登陆功能对应的用户输入校验方法
public void validateLogin() {
if(username == null || username.trim().equals("")){
addFieldError("username","
用户名不能为空
.");
}
if(password == null || password.trim().equals("")){
addFieldError("password", "
密码不能为空
.");
}else if(password.length()<6 || password.length()>12){
addFieldError("password", "
密码长度应在
6
到
12
位之间
.");
}
}
//
用户注册功能对应的用户输入校验方法
public void validateRegist() {
if(username == null || username.trim().equals("")){
addFieldError("username", "
用户名不能为空
.");
}
if(password == null || password.trim().equals("")){
addFieldError("password", "
密码不能为空
.");
}else if(password.length()<6 || password.length()>12){
addFieldError("password", "
密码长度应在
6
到
12
位之间
.");
}
if(age <0 || age>100){
addFieldError("age", "
年龄不符合要求
.");
}
if(email.indexOf("@") == -1){
addFieldError("email", "Email
格式不符合要求
.");
}
}
public String login(){
return "success";
}
public String regist(){
return "success";
}
}
以上代码中用户输入校验方法名编写时务必注意
: 1.为
validateXxx方法
,方法名
Xxx为对应的逻辑方法方法名,首字母大写。
2. 方法的权限为
public,方法没有参数,返回值为
void类型。
struts.xml文件中当前的
Action类对应的每个
action配置都需要包含名为“
input”的结果视图,具体的配置信息如下所示:
<?xml version="1.0"encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTDStruts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name=
"default"namespace=
"/" extends=
"struts-default">
<action name="login"class="com.study.erp.action.UserAction" method="login">
<result name="input">/Login.jsp</result>
<result name="success">/LoginSuccess.jsp</result>
</action>
<action name="regist"class="com.study.erp.action.UserAction" method="regist">
<result name="input">/Regist.jsp</result>
<result name="success">/RegistSuccess.jsp</result>
</action>
</package>
</struts>
用户注册视图
Regist.jsp
代码如下所示
:
<%@ pagelanguage="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ tagliburi="/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>
用户注册页面
</title>
</head>
<body>
<h1>
用户注册
</h1>
<hr>
<s:form action="regist.action">
<s:textfield name="username" label="用户名"></s:textfield>
<s:password name="password" label="密码"></s:password>
<s:textfield name="age" label="年龄"></s:textfield>
<s:textfield name="email" label="电子邮件:"></s:textfield>
<s:submit name="login" value="注册"/>
</s:form>
</body>
</html>
以上为实现登陆和注册功能的主要代码,我们仔细分析发现
validateLogin()
和
validateRegist()
代码中部分代码是重复的,但是上面的代码中由于用户输入验证对应的方法是不同的,所以代码出现了重复的现象,虽然我们可以单独把这段重复的代码单独写到一个方法中,然后在这两个用户输入验证方法中进行调用以进行改进。
Struts2
框架的
validate
方法是由
DefaultWorkFlowInterceptor
拦截器调用的。该拦截器包含在
defaultStack
拦截器栈中。因此,只要使用默认的拦截器栈该拦截器都回被运行,从而
validate
方法会被调用。换句话说,默认情况下当前
Action
的所有逻辑方法执行之前都会执行
validate
方法。如果
validate
方法和
validateXxx
方法同时存在,它们的执行顺序是先执行
validateXxx
方法,再执行
validate
方法。针对于
Struts
框架中本例中的
Action
类可以做如下优化:
packagecom.study.erp.action;
importcom.opensymphony.xwork2.ActionSupport;
public class UserActionextends ActionSupport{
private String username;
private String password;
private int age;
private String email;
//此处省略属性对应的
get和
set方法
….
//用户登陆功能对应的用户输入校验方法,此时本方法可以省略不写
public void validateLogin() {
}
//用户注册功能对应的用户输入校验方法
public void validateRegist() {
if(age <0 || age>100){
addFieldError("age", "年龄不符合要求.");
}
if(email.indexOf("@") == -1){
addFieldError("email", "Email格式不符合要求.");
}
}
//用户输入验证方法
public void validate(){
if(username == null || username.trim().equals("")){
addFieldError("username", "用户名不能为空.");
}
if(password == null || password.trim().equals("")){
addFieldError("password", "密码不能为空.");
}else if(password.length()<6 || password.length()>12){
addFieldError("password", "密码长度应在6到12位之间.");
}
}
public String login(){
return "success";
}
public String regist(){
return "success";
}
}
如果某
action
中包含了多个逻辑方法,其中绝大部分方法都有相同的验证规则,只有个别方法不需要该验证规则时。可以使用
DefaultWorkFlowInterceptor
拦截器的
excludeMethods
参数,指定被排除的方法。如果被排除的方法超过
1
个,方法名中间使用逗号进行间隔。
例如
UserAction
类中包含了
3
个方法:用户登陆
login
方法,用户注册
regist
方法,用户信息删除的
delete
方法。而用户信息删除不需要执行
validate
方法用户名和用户密码的验证规则。具体的实现方法可以包括以下两种,比较而言第二种方法更容易理解也更加简单。
1
.重新设定默认的拦截器栈,在该拦截器栈中将
delete
方法排除掉。对应的
struts.xml
文件的内容如下所示:
<struts>
<package name=
"default"namespace=
"/" extends=
"struts-default">
<interceptors>
<interceptor-stackname="mydefaultStack">
<interceptor-refname="defaultStack">
<paramname="workflow.excludeMethods">delete</param>
</interceptor-ref>
</interceptor-stack>
</interceptors>
<default-interceptor-refname="mydefaultStack"></default-interceptor-ref>
<action name=
"login"class=
"com.study.erp.action.UserAction" method=
"login">
<result name=
"input">/Login.jsp</result>
<result name=
"success">/LoginSuccess.jsp</result>
</action>
<action name=
"regist"class=
"com.study.erp.action.UserAction" method=
"regist">
<result name=
"input">/Regist.jsp</result>
<result name=
"success">/RegistSuccess.jsp</result>
</action>
<action name=
"delete"class=
"com.study.erp.action.UserAction" method=
"delete">
<result name=
"success">/DeleteSuccess.jsp</result>
</action>
</package>
</struts>
2
.只在删除用户信息对应的
action
配置信息中将
delete
方法从拦截器中删除掉。对应的配置文件内容
<?xml version="1.0"encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTDStruts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name=
"default"namespace=
"/" extends=
"struts-default">
<action name=
"login"class=
"com.study.erp.action.UserAction" method=
"login">
<result name=
"input">/Login.jsp</result>
<result name=
"success">/LoginSuccess.jsp</result>
</action>
<action name=
"regist"class=
"com.study.erp.action.UserAction" method=
"regist">
<result name=
"input">/Regist.jsp</result>
<result name=
"success">/RegistSuccess.jsp</result>
</action>
<action name=
"delete"class=
"com.study.erp.action.UserAction" method=
"delete">
<result name=
"success">/DeleteSuccess.jsp</result>
<interceptor-ref name="defaultStack">
<paramname="workflow.excludeMethods">delete</param>
</interceptor-ref>
</action>
</package>
</struts>
转载于:https://blog.51cto.com/5926725/1066861