Struts2对输入数据进行验证

根据实验四的图书管理系统,扩展图书新增功能,要求对新增页面表单中的每个文件输入框进行输入校验

书名 String 必须输入;长度在4-80之间
作者 String 必须输入;长度在4-40之间
书号(13位ISBN) String 必须输入;长度必须是13位;根据参考资料中的ISBN校验码的计算方法对书号的有效性进行校验。
出版社 String 文本中必须包含“出版社”一词
出版日期 Date 日期范围为1900年1月1日到当前日期
价格 Double 最小值为0.0
库存数量 Integer 最小值为0

验证方法

  1. 客户端验证

    数据提交前在客户端验证
    可使用JavaScript或者JQuery实现
    特点:减少客户等待时间,减小服务器压力

  2. 服务端验证

    在数据提交后服务器端验证
    特点:防止“绕过”客户端验证提交非法数据
       可以在服务器端处理数据前确保数据的合法性

  3. 验证方式
    1. 使用ActionSupport编码实现验证
    2. 使用验证框架实现验证

ActionSupport编码实现验证(重)

  1. Action类的方法中直接验证
  2. 重写Validate()
  3. 使用validateXxx()

添加错误信息

  1. addFieldError(String fieldName,String errorMessage)添加字段的错误信息
  2. addActionError(String anErrorMessage)添加与Action所处理业务相关的错误信息

addFieldError的使用方法
action.java
在这里插入图片描述
xml
在这里插入图片描述
表单前端
在这里插入图片描述
在这里插入图片描述
注意 有时会报错 No result defined for action…and result input都和这个有关系

 <result name="input">BookListAdd.jsp</result>

其中 Struts2应用在运行过程中若发现addFieldError()中有信息或者类型转换失败或着输入校验失败等情况。详细查看 https://blog.csdn.net/lv_hang515888/article/details/73456789
那么它会自动跳转到name为input的,然后转到INPUT所对应的页面
Action中的属性值为空的时候,Struts2的默认拦截器会报错,但是又找不到input的Result,不能够把错误返回,所以报这种错误。
这里是因为使用了addFieldError()。
报错原因:

1、validate方法没有通过(表单验证看看有没有重名,导致js文件加载过慢);
2、页面元素中有重命名时,但后台action类的对应的接收此同名参数的是变量而没有写成数组
3、配置文件中result 返回.jsp出现错误(多了空格、或者没有界面)
4、对应Action中没有返回值,或者返回值数据类型转换出错
5、工程里有一个BaseAction的类,并且BaseAction使用了验证框架,有一个BaseAction-validation.xml的文件。
而PoiterAction正好是BaseAction的一个子类,也继承了父类的验证框架,因此按照验证框架的运行流程来看这个问题就很明显了。由于验证框架在调用子类的时候首先加载父类的验证规则,然后等待输入,系统会找到input元素制定的JSP文件的输入信息,但是PoiterAction并没有input项,所以系统抛出No result defined for action…and result input。
6、表单中有文件上传功能,提交form表单时,需要加enctype = “multipart/form-data”
比如<form action="xxxx.action" method="post" name="xxx" id="xxx"enctype = "multipart/form-data">
果不加enctype = "multipart/form-data"这个,在不同浏览器版本中,比如谷歌 52版本,不加也不会报错,但在58版本就报错了。所以避免浏览器兼容问题,最好加上!

业务方法中较验

前端页面

<body>
<!--  判断字段是否有错误信息-->
<s:if test="hasFieldErrors()">
<h1 align="center">输出错误字段信息</h1>
<div align="center" style="color:blue;">
使用s:fielderror输出一个指定的错误信息
<s:fielderror name="user.username" />
使用s:fielderror输出全部的错误信息
<s:fielderror />
</div>
</s:if>
<!-- 判断action是否有错误 -->
<s:if test="hasActionErrors()">
<h1 align="center">输出错误Action信息</h1>
<div  align="center" style="color:gray;">
使用s:actionerror输出action相关的错误信息
<s:actionerror/>
</div>
</s:if>
<h1>使用execute业务方法直接较验</h1>
<s:form action="register.action" method="post" >
<s:textfield label="用户名"  name="user.username"/>
<s:password  label="密码" name="user.password"/>
<s:textfield label="年龄" name="user.age" />
<s:textfield  label="邮箱" name="user.email"/>
<s:submit  value="提交" /><s:reset value="重置" /><br/>
</s:form>
<s:debug/>
</body>

action.java

public class UserAction extends ActionSupport {
    private User user;

    @Override
    public String execute() throws Exception {
        if(null==user.getUsername() || "".equals(user.getUsername())){
            this.addFieldError("user.username", "用户名不能为空!");
        }
        if(null==user.getPassword() || "".equals(user.getPassword())){
            this.addFieldError("user.password", "密码不能为空!");
        }
        String ageStr="^\\d{1,3}$";
        Pattern ageReg=Pattern.compile(ageStr);
        Matcher ageMatcher=ageReg.matcher(user.getAge()+"");
        if(!ageMatcher.matches()){
            this.addFieldError("user.age", "年龄只能是数字,并只能为1-200之间!");
        }
        if(null==user.getAge()){
            this.addFieldError("user.age", "年龄不能为空!");
        }
    
        String emaString="^\\w+@\\w+(.\\w{2,3}){1,2}$";
        Pattern emailReg=Pattern.compile(emaString);
        Matcher emailMatcher=emailReg.matcher(user.getEmail());
        if(!emailMatcher.matches()){
            this.addFieldError("user.email", "邮箱格式不正确");
        }
        if(this.hasErrors()){
            this.addActionError("输入的注册信息有误");
            return INPUT;
        }
        return SUCCESS;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
    
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这里主要介绍了三种方式显示Validation的错误信息显示方式,Validation的原理是由内置的验证拦截器在配置校验规则后,一旦不符合规则,拦截之后返回一个错误集合,如果直接使用<struts:fielderror/>则遍历错误集合,打印所有信息,如果指定了变量名,<struts:fielderror><struts:param></struts:param></struts:fielderror>则只打印指定字段的校验错误信息。同时,如果使用了Struts标签构造表单,那么错误信息会默认出现在输入框上方。参考: http://blog.csdn.net/drohe/article/details/72972320

在validate中验证

在这里插入图片描述

不管请求的action是哪个方法,validate方法都会被调用

在这里插入图片描述

在validateXXX()中验证

通过validateXxx()方法实现, validateXxx()只会校验action中方法名为Xxx的方法。其中Xxx的第一个字母要大写。当某个数据校验失败时,我们应该调用addFieldError()方法往系统的fieldErrors添加校验失败信息(为了使用addFieldError()方法,action可以继承ActionSupport ),如果系统的fieldErrors包含失败信息,struts2会将请求转发到名为input的result。在input视图中可以通过<s:fielderror/>显示失败信息。

public String add() throws Exception{  return "success";}   
public void validateAdd(){  
          if(username==null && "".equals(username.trim()))  this.addFieldError("username", "用户名不能为空");  
}  

在这里插入图片描述

public static void invokePrefixMethod(com.opensymphony.xwork2.ActionInvocation actionInvocation, 
java.lang.String[] prefixes) 
	throws java.lang.reflect.InvocationTargetException, java.lang.
	IllegalAccessException { /* compiled code */ }

在这里插入图片描述

输入校验的流程

1、类型转换器对请求参数执行类型转换,并把转换后的值赋给action中的属性。

2、如果在执行类型转换的过程中出现异常,系统会将异常信息保存到ActionContext,conversionError拦截器将异常信息添加到fieldErrors里。不管类型转换是否出现异常,都会进入第3步。

3、系统通过反射技术先调用action中的validateXxx()方法,Xxx为方法名。
4、再调用action中的validate()方法。

5、经过上面4步,如果系统中的fieldErrors存在错误信息(即存放错误信息的集合的size大于0),系统自动将请求转发至名称为input的视图。如果系统中的fieldErrors没有任何错误信息,系统将执行action中的处理方法。

验证框架以后再说

猜你喜欢

转载自blog.csdn.net/qq_40803626/article/details/89048869