在前一篇博客 Struts2框架之Struts内置的form以及设置错误回显中,演示了struts中的内置form标签以及错误信息的初步回显,这一篇将对表单字段进行逐一检查,并且返回错误信息给前端。
在Struts2框架中常见的验证表单方式有两大类,一类是在Action
使用validate()
方法,来自ActionSupport
类,并配合addFieldError
方法,第二类是通过使用xml声明式验证。下面将讲解一下第一类验证表单的方法。
1、
首先需要明确,validate()
方法来自ActionSupport
类,所以你的Action类必须继承ActionSupport
类。
其二是,前端JSP界面必须要使用struts中的内置form标签,否则后端返回的字段错误信息无法显示在前端。
2、用户注册Demo
①、Demo目录结构
②、后端源码
User模型类
package cn.hestyle.model;
import java.util.Date;
public class User {
private String username;
private String password;
private String email;
private Date birthday;
private String hobbies;
private boolean married;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getHobbies() {
return hobbies;
}
public void setHobbies(String hobbies) {
this.hobbies = hobbies;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public boolean isMarried() {
return married;
}
public void setMarried(boolean married) {
this.married = married;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", email='" + email + '\'' +
", birthday=" + birthday +
", hobbies='" + hobbies + '\'' +
", married=" + married +
'}';
}
}
UserAction动作类
package cn.hestyle.web.action;
import cn.hestyle.model.User;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.interceptor.validation.SkipValidation;
/**
* 通过实现ModelDriven<User>接口,封装表单信息为User模型
*/
public class UserAction extends ActionSupport implements ModelDriven<User> {
//user的各个属性必须实现getter、setter方法,并且user需要手动new出来
private User user = new User();
/**
* 接口ModelDriven<User>需要实现的方法
* @return
*/
@Override
public User getModel() {
return user;
}
/**
* ActionSupport中的方法
*/
@Override
public void validate() {
String username = user.getUsername();
String password = user.getPassword();
//检查用户名字段合法性
if (StringUtils.isEmpty(username)){
//addFieldError添加字段错误,第一个参数需要与前端表单项匹配
addFieldError("username", "用户名不能为空");
} else if (username.length() < 5 || username.length() > 10) {
addFieldError("username", "用户名的长度5-10");
}
//检查密码字段合法性
if (StringUtils.isEmpty(password)){
addFieldError("password", "密码不能为空");
} else if (password.length() < 6 || password.length() > 12) {
addFieldError("password", "密码的长度6-12");
}
//检查邮箱字段合法性,使用正则匹配
if (!user.getEmail().matches("^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$")) {
addFieldError("email", "邮箱格式错误!");
}
if (user.getBirthday() == null) {
addFieldError("birthday", "日期格式yyyy-MM-dd");
}
}
/**
* 注册action处理方法
* @return
*/
public String register(){
System.out.println(user);
return "success";
}
/**
* 欢迎action处理方法
* @return
*/
public String welcome(){
return "welcome";
}
}
③、前端页面
index.jsp注册页面
<%--
Created by IntelliJ IDEA.
User: hestyle
Date: 2019/10/20
Time: 2:35 下午
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8"%>
<%-- 使用struts中的标签需要导入struts-tags --%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>用户注册</title>
</head>
<%-- 设置错误信息为红色(突出样式) --%>
<s:head></s:head>
<body>
<s:form action="register">
<s:textfield name="username" label="用户名" requiredLabel="true" requiredPosition="right"/>
<%-- showPassword的作用是当表单中字段出现问题时,把之前提交的表单回显保留 --%>
<s:password name="password" label="密码" showPassword="true" requiredLabel="true" requiredPosition="right"/>
<s:textfield name="email" label="邮箱"/>
<s:textfield name="birthday" label="生日"/>
<%--
checkboxlist复选框,
list是复选框的选项,第一个'编码'是value(提交到后端action中的值),第二个'编码'是选项名称,后面依次类推
--%>
<s:checkboxlist name="hobbies" label="爱好" list="#{'编码':'编码', '撩妹':'撩妹', '加班':'加班'}"/>
<%--
radio单选框
list是复选框的选项,第一个'true'是value(提交到后端action中的值),第二个'已婚'是选项名称,后面依次类推
--%>
<s:radio name="married" label="婚姻状况" list="#{'true':'已婚', 'false':'未婚'}"/>
<s:submit value="注册"></s:submit>
</s:form>
</body>
</html>
success.jsp页面
<%--
Created by IntelliJ IDEA.
User: hestyle
Date: 2019/10/22
Time: 5:01 下午
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>注册成功!</title>
</head>
<body>
注册成功!
</body>
</html>
welcome.jsp页面
<%--
Created by IntelliJ IDEA.
User: hestyle
Date: 2019/10/23
Time: 9:48 上午
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>xxx主页</title>
</head>
<body>
欢迎访问!
</body>
</html>
④、struts配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<!-- 开启开发模式(如果出现exception将会提示更详细的信息)-->
<constant name="struts.devMode" value="true"></constant>
<package name="user" extends="struts-default">
<!--申明register动作,使用UserAction中的register方法处理-->
<action name="register" class="cn.hestyle.web.action.UserAction" method="register">
<!--input表示的是表单出现错误,重新返回到注册页面-->
<result name="input">/index.jsp</result>
<result name="success">/success.jsp</result>
</action>
<!--申明welcome动作,使用UserAction中的welcome方法处理-->
<action name="welcome" class="cn.hestyle.web.action.UserAction" method="welcome">
<result name="welcome">/welcome.jsp</result>
</action>
</package>
</struts>
⑤、浏览器访问效果
3、全局与局部之分
在动作类如果使用ActionSupport
类中的validate()
方法验证表单(如上面的UserAction
类),设置的是该Action类中全局表单检查,也就是说该Action中的所有动作都会强制验证表单。
但是Action类中可能存在一些没有表单提交的动作,也就是不需验证表单。比如UserAction
中的welcome
动作。
此时如果我们直接访问welcome动作会报错,因为welcome没有表单,但是UserAction中配置的是整个Action类全局的表单验证。
方法一:
这时我们可以给不需要验证表单的方法加上@SkipValidation
注解,表示跳过validate()
方法。
方法二:
将Action类中的validate()
方法修改为validate+动作名()
方法。
比如UserAction类中的register方法需要表单验证,为它专门写一个表单验证方法validateRegister()
,注意这个为动作定制表单验证方法名是固定的格式,不可修改!
以上就是Struts2框架之Action中进行表单验证主要内容,主要就是注意下全局、局部表单验证方法的区别。
特别说明一下,其中ModelDriven<User>
的作用是将表单转换为User模型。
参考我的博客 Struts2框架之Action获取请求参数的四种方式