二 业务方法中验证
我们希望用户在前端表单填写数据,进行提交,如果错误了,就返回相应的错误信息,如果没有任何错误,就通过。
业务方法验证可以分为三个部分。
二.一 开发者自己手动验证
如用户登录时的验证:
//第一种情况: 在登录方法中直接进行验证 public String login(){ //1. 接收到各个数据,如用户名,密码,邮箱等. String userName="两个蝴蝶飞"; String password="yjl"; String email="1290513799@qq.com"; //2. 判断用户名是否错误,如果出现了错误,就this.addFieldError("userName","用户名错误"); if(!"两个蝴蝶飞".equals(userName)){ this.addFieldError("userName","用户名错误"); } //3. 判断密码是否错误,如果出现了错误,就this.addFieldError("password","密码错误"); if(!"yjl".equals(password)){ this.addFieldError("password","密码错误"); } //4. 判断邮箱是否错误,如果出现了错误,就this.addFieldError("email","邮箱错误"); if(!"1290513799@qq.com".equals(email)){ this.addFieldError("email","邮箱错误"); } //5. 判断在这个action中是否出现了错误,如果有错误,将其添加到Action中,返回输入的界面 if(this.hasErrors()){ //也有hasFieldErrors()和hasActionErrors(), hasErrors()包括field错误和action错误 this.addActionError("登录的输入数据不对"); return "loginUI"; } //6.现在才是进行正常的逻辑操作,上面都是数据的检测(第一步获取数据除外) //判断是否登录成功,如果成功返回到成功界面, 如果不成功,返回到登录的界面, //... 登录业务 return SUCCESS; }
需要我们自己写验证代码,且不具有通过性,每一个方法,如注册方法register() 也需要进行验证。
二.二 重写 validate() 方法
二.二.一 Validateable 接口定义
ActionSupport 的类定义如下:
public class ActionSupport implements Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable{ }
里面实现了一个验证接口 Validateable
该接口 Validateable 里面有一个validate()方法
public interface Validateable { /** * Performs validation. */ void validate(); }
UserAction 继承了ActionSupport类,故继承了validate()方法,开发者 需要重写validate()方法即可。
数据验证,写在了 validate() 方法里面,正常的登录代码写在了 login() 方法里面,
数据验证与业务逻辑进行了分离。
那么此时,登录的逻辑判断就可以写成:
二.二.二 重写 validate() 方法进行验证
//第二种方式,重写validate()方法进行验证 public String login(){ //1. 接收到各个数据,如用户名,密码,邮箱等. String userName="两个蝴蝶飞"; String password="yjl"; String email="1290513799@qq.com"; //5. 判断在这个action中是否出现了错误,如果有错误,将其添加到Action中,返回输入的界面 if(this.hasErrors()){ //也有hasFieldErrors()和hasActionErrors(), 这是两个方法的错误相加 this.addActionError("登录的输入数据不对"); return "loginUI"; } //直接判断型业务逻辑,不用管数据验证。(当然前面有一个检测的操作) //判断是否登录成功,如果成功返回到成功界面, 如果不成功,返回到登录的界面, //用addFieldError或者addActionError添加错误信息 return SUCCESS; } @Override public void validate() { //只关注数据的验证 //1. 接收到各个数据,如用户名,密码,邮箱等. String userName="两个蝴蝶飞"; String password="yjl"; String email="1290513799@qq.com"; //2. 判断用户名是否错误,如果出现了错误,就this.addFieldError("userName","用户名错误"); if(!"两个蝴蝶飞".equals(userName)){ this.addFieldError("userName","用户名错误"); } //3. 判断密码是否错误,如果出现了错误,就this.addFieldError("password","密码错误"); if(!"yjl".equals(password)){ this.addFieldError("password","密码错误"); } //4. 判断邮箱是否错误,如果出现了错误,就this.addFieldError("email","邮箱错误"); if(!"1290513799@qq.com".equals(email)){ this.addFieldError("email","邮箱错误"); } }
二.二.三 流程处理
在进入login()方法之前,首先会调用validate()方法,进行数据验证。
相比较第一种方式,这个时候便处理上简单了一些。
但还是有一些特别严重的问题。 那就是在访问UserAction时,在进入每一个方法之前,都会先调用validate()方法。
如: UserAction 中 还存在 toLogin 和 register() 方法:
public String toLogin(){ //先调用validate()方法 return "login"; } public String register(){ //先调用validate()方法 return "register"; }
然而,实际生活中, 登录时的验证与注册时的验证,验证数据的多少是不一样的,如注册时验证性别不为空,居住地不为空,
在登录时是不需要验证的,还有确认密码登录时是没有的。
更有的情况,登录和注册时对同一数据的验证规则是不一样的(根据具体业务情况分析),
如注册时需要验证用户名是否存在,登录时不需要验证用户名是否存在。
这个时候,需要在validate()方法中进行大量的判断,如果方法名login,走哪个验证,是register(),起哪个验证,是toLogin()的话,不走验证。
二.三 针对单个方法分别进行验证
需要注意,这个时候,验证数据的方法名称必须符合validateXxx()的形式。
如果是对login() 方法进行验证,那么验证login数据是否正确的方法名称必须是 validateLogin(),
如果是对register() 方法进行验证,那么验证reigster 数据是否正确的方法名称必须是 validateRegister().
对login()和register()方法分别进行验证:
public String login(){ if(this.hasErrors()){ this.addActionError("登录的输入数据不对"); return "loginUI"; } return "login"; } public String register(){ if(this.hasErrors()){ this.addActionError("注册的输入数据不对"); return "loginUI"; } return "register"; } public void validateLogin(){ //对登录表单中的数据进行验证 } public void validateRegister(){ //对注册表单中的数据进行验证 }
有人会问,在注册时出现了错误,已经将数据放入到Action中了,即hasErrors()为true了,那么进入login()方法,取出的数据不就是true吗? 这是一个误区。
Strtus2是多实例的,在进入register()方法时,会重新实例化对象,所有的数据都会清空(静态属性和代码块除外),包括错误信息。
在进入login()时,也会重新实例化一下,会清空的。 需要设置 scope=“prototype”。
这种方式相对于第二种来说,可读性大大增强,但每一个方法都要验证数据,都需要写一个validateXxx()方法,会导致验证方法过多。
注意,当Action既有 validate()方法,也有validateLogin()方法时,如果执行的是login操作时,
那么会先执行validateLogin()方法,
再执行validate()方法,有一个先后的顺序,但是两者均起作用的。
(图片摘自森林森前辈的Struts2(十二),本章图片均来自于此,谢谢。
源址为:https://www.cnblogs.com/liunanjava/p/4383237.html)
常常用 Validate 框架进行验证。
三. validate框架验证数据
使用验证框架的好处, 1.验证实现的部分方便复用和扩展,2.验证的实现和业务处理分离。
验证里的配置需要在 xml文件中进行相应的配置。
这里验证一些常见的属性,用User类进行相应的包装。
三.一 未使用框架验证之前
三.一.一 编写 User.java
/** * @author 两个蝴蝶飞 * @version 创建时间:Sep 8, 2018 2:46:59 PM * 用于包装框架数据的实体类,没有实际意义 */ public class User { /** * @param id 编号id * @param userName 用户名 * @param password 密码 * @param name 真实姓名 * @param sex 性别 * @param age 年龄 */ private Integer id; private String userName; private String password; private String name; private String sex; private int age; }
属性需要实现setter和getter方法,也添加一个 toString() 方法。
三.一.二 编写 RegisterAction 类
里面定义跳转到注册和注册的两个方法:
/** * @author 两个蝴蝶飞 * @version 创建时间:Aug 30, 2018 8:21:09 PM * User的相关验证 */ public class RegisterAction extends ActionSupport{ private static final long serialVersionUID = 1L; private static Logger logger=Logger.getLogger(UserAction.class); private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } public String toRegister(){ logger.info("跳转到注册页面"); return "registerUI"; } public String register(){ logger.info("执行注册的功能"); logger.info("用户名是:"+user.getUserName()+",密码是:"+user.getPassword()); return "register"; } }
三.一.三 配置 struts.xml
<action name="Register_*" class="com.yjl.web.action.RegisterAction" method="{1}"> <result name="registerUI">/WEB-INF/content/register.jsp</result> <result name="register">/WEB-INF/content/success.jsp</result> <!--错误后,跳转到此页面--> <result name="input">/WEB-INF/content/register.jsp</result> </action>
三.一.四 编写 /content/register.jsp
<body> <h3>这是一个注册框架的页面</h3> <s:if test="hasFieldErrors()"> <s:fielderror></s:fielderror> </s:if> <s:form action="Register_register" method="post" namespace="/"> <s:textfield label="编号" name="user.id"></s:textfield> <s:textfield label="用户名" name="user.userName"></s:textfield> <s:textfield label="密码" name="user.password"></s:textfield> <s:textfield label="确认密码" name="repassword"></s:textfield> <s:textfield label="真实姓名" name="user.name"></s:textfield> <s:radio label="性别" list="#{'m':'男','f':'女'}" name="user.sex"></s:radio> <s:textfield label="年龄" name="user.age"></s:textfield> <s:submit value="提交"/> </s:form> </body>
/content/success.jsp 的内容显示 注册成功
<body> 注册成功 </body>
三.一.五 重启服务器,进行验证
网址是: http://localhost:8080/Struts_Validate/Register_toRegister
点击提交,页面正常跳转
日志打印输出:
这个时候,环境已经搭建成功了。
现在并没有进行相应的验证操作。
接下来就是具体的验证。