zoukankan      html  css  js  c++  java
  • struts2(四)之输入校验

    前言

      这个本来是昨天就写好的,但是不知道为什么没有保存成功!但是今天起来再写一遍就当巩固一下知识吧。

    一、输入校验概述

      在以前我们写一个登录页面时,并没有限制用户的输入,不管用户输入什么,我们都存入数据库中,很显然这是不行的,我们需要检测用户输入的文本是否合法,

      是否符合我们需要的文本格式,符合就放行,而struts2中就有这种功能,能帮我们在服务器段进行判断,比如用户名不能为空,年龄只能在0-100之间等。现在

      我们就来说说如何使用struts2中的校验功能把。

      分为两种:编程式校验和配置校验(XML配置校验)

    1)验证方式

      客户端验证:javascript

      服务端验证:逻辑验证

      注意:如果客户端和服务端验证二选一,服务端必不可少。用户的输入验证,必须做,且工作量巨大。

      实际开发中:服务端+客户端都需要验证

    2)struts2的服务验证

      在struts2的框架中,它也提供了一个Map<表单的字段名,错误提示>,我们要做的:往map中存放错误信息

    二、编程式校验

    2.1、前提条件

      前提:动作类必须继承ActionSupport  

          重写validate方法

      注意:

         1)validate方法会在动作方法执行之前,进行验证。

         2)实现Validateable接口,重写其中的validate方法,因为我们的action继承自actionSupport,actionsupport帮我们实现了这接口

           所以我们只需要重写validate方法即可。

    2.2、细说编程式校验

      

      在这里使用了一个addFieldError("xxx","yyy"); 将错误信息存起来,等回到页面在显示出来,如何显示呢?

      如果使用的是s标签提交的表单,那么该会自动显示出来如果不是,则需要手动将其输出,<s:fielderror fieldName="xxx">.。并且如果使用了,addFieldError中存有了信息,

      则不会在前往原先action所需要跳转的页面,而是找到result为input的结果码对应的页面。所以,如果需要使用它,那么在struts.xml中应该编写一个结果码为input的代码

      为什么需要input结果码等?原因是这种输入校验依靠了两个拦截器,如图所示:

        

      这种数据检验都是在数据进行类型转换之后做的事情,从图中的几个拦截器就可以看先后执行顺序,也可以解释为什么需要input结果码了。

      对单个方法或指定方法进行数据校验。

      上面这种对所有方法校验有些不符合我们的要求,因为并不是每个方法都需要提交表单参数过来的,所以struts2中有两种办法解决这个问题:

        1)还是对所有方法进行校验,不过可以将我们不需要使用校验的方法上用注解@SkipValidation进行跳过即可

        2)指定校验某个方法, 比如validateAdd()这就只校验add方法, validateLogin() 值校验login方法,以这样的格式进行命名,就是对特定方法进行校验了。

      注意:指定某个方法校验会在公共校验方法之前被调用,也就是说会先执行validateXXX(),然后在执行validate()方法

    2.3、编程式校验之demo

      1)在动作类UserAction中继承AcctionSupport,重写Validate方法

        

        备注:StringUtils是struts框架中org.apache.commons.lang3.StringUtils,jar包中的,增强了String的功能。

        

      2)register.jsp

        

      3)配置struts.xml文件

        

      4)测试(没有输入用户名直接按注册)

        

      问题:当重写了validate方法,它会对动作类中的所用动作方法进行验证。

        举例:

        

        在UserAction中添加动作方法

        

        testValidate.jsp

        

        最后创建一个index.jsp用来测试

        

        结果:

        

        当我们注释掉Validate方法时:

       

      解决验证所有动作方法的问题:   

        第一种方式:
          使用@SkipValidation的注解

          就是我们不需要去验证testValidate方法我们就在定义方法的上面进行注释
         第二种方式:
           定义验证方法的名称:validate+动作名称 动作名称的首字符还要大写

      public void validateRegister(){
            if(StringUtils.isEmpty(user.getUsername())){
                //存入错误信息,直接调用父类的addFieldError方法,存入错误信息。第一个参数是表单name属性的值。第二个参数是错误提示
                addFieldError("username", "请输入用户名");
            }

      编程式验证弊端:硬编码

    三、XML校验

      通过编写验证规则的xml文件。需要验证时,编写xml文件,不要验证,就不要写。

      优点:解决了编程式验证的弊端

    3.1、前提条件

      1)必须实现validateable接口,actionsupport已经实现了,所以我们只需要直接继承actionsupport即可 

      2)action中必须为属性提供getXXX、setXXX方法,因为代码校验是在Action本类中来完成校验,这说明我们可以直接使用本类的private属性,但如果使用

        XML配置方式校验,这需要使用校验框架的代码来完成校验工作,那么校验框架需要调用Action的getXXX()方法来获取被校验的属性,所以一定要为被

        校验的属性提供getXXX()方法。

    3.2、创建校验配置文件

      1)命名规范

        actionClass-actionName-validation.xml  

           actionClass:action的类名

           actionName:action的访问名称,及在struts.xml中配置的,<action name="">

           validation.xml:固定后缀名。 

        比如:Demo02Action-Demo02Action_add-validation.xml    这种是对特定方法进行校验

      2)路径

        必须与action同包下

        

    3.3、编写校验文件

      校验文件的DTD:在xwork-core-x.x.x.jar中找到xwork-validator-x.x.x.dtd,打开它,内部会有一段DTD,我们把它copy过来,放到我们的校验文件中。    

      

      1)内置校验器

        Struts内置的常用声明式验证器位置:

          在xwork-core-xxx.jar/com.opensymphony.xwork2/validator/validators/default.xml中就能够找到所有的校验规则。

          我的在

        

        详解:

        

      2)如何使用校验器

        如果想要查看某个校验规则如何使用的话,看源码,然后打开Javadoc进行查看,其中会有例子让我们查看的。比如,我需要查看requiredstring的使用方法。

        复制requiredstring的class:

          

        按shift+ctrl+t对该类进行查找:

          

        查看文档:

          

    3.4、针对动作类的所有动作进行验证

      在动作类所在的包中,建立一个ActionClassName-validation.xml的文件 

      

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE validators PUBLIC
              "-//Apache Struts//XWork Validator 1.0.3//EN"
              "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
    <!-- 当使用ActionClassName-validation.xml来命名文件时,它是一个动作类验证器。会验证动作类中的所有动作方法 -->
    <validators>
        <!-- 基于字段的声明式验证 -->
        <!-- field中name属性指定的是表单name属性的取值 -->
        <field name="username">
            <!-- struts2框架为我们集成了很多的内置验证器。requiredstring会验证输入内容是否为空,是否为空字符串。并且去掉左右空格-->
            <field-validator type="requiredstring">
                <message>请输入用户名</message>
            </field-validator>
        </field>
    </validators>

      这是一个会验证所有动作方法的,又回到了我们上面编程式验证所遇到的问题。那我们怎么去解决呢?

        解决一:使用@SkipValidation的注解

        解决二:定义一个针对验证动作类中某个动作方法的xml  

    3.5、.针对动作类中的某个动作进行验证

      在动作类所在的包中建立一个xml文件,名称为ActionClassName-ActionName-validaton.xml的文件

      内容和上面的一样,只是修改一下名称。

      测试:

      

    3.6、基于验证器的验证

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE validators PUBLIC
              "-//Apache Struts//XWork Validator 1.0.3//EN"
              "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
    <!-- 当使用ActionClassName-ActionName-validation.xml来命名文件时,它是一个指定动作方法的验证器。只会验证指定的动作方法 -->
    <validators>
        <field name="username">
             <field-validator type="requiredstring">
                 <message>请输入用户名必须要输入</message>
             </field-validator>
        </field>
        
        <!-- 基于验证器的验证 -->
        <validator type="requiredstring">
            <!-- 以注入的方式,提供要验证的字段信息 
            setFieldName("password");
            -->
            <param name="fieldName">password</param>
            <message>密码必须输入</message>
        </validator>
    </validators>

      为什么param中的name是filedName呢?

      1)我们可以查看一下源码:

           

      2)查看的源码

      3)查找父类

        

      4)查看源码

        

    四、基于XML验证的实例

      1)编写一个Student.java

    package com.jxlg.domain;
    
    import java.io.Serializable;
    /**
     * URL:uniform resource locator 统一资源定位符
     * http://localhost:6060/studentManagement/home.jsp
     * 协议            主机                 端口             URI
     * URI:uniform resource identifier 统一资源标识符
     * studentManagement/home.jsp
     * @author Shinelon
     *
     */
    public class Student implements Serializable {
        private String username;//不能为null和空字符串。要去空格
        private int age;//整数,介于18-100之间
        private String email;//按照邮箱的格式输入
        private String password;//密码。长度3-8位
        private String repassword;//确认密码,必须和密码一致。写在这里的目的,完全是为了演示验证器的使用。实际开发中根本不会保存确认密码。
        private int score;//成绩,必须是自然数
        private String url;//个人主页:必须符合url格式
        private String gender;//性别
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public String getEmail() {
            return email;
        }
        public void setEmail(String email) {
            this.email = email;
        }
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }
        public String getRepassword() {
            return repassword;
        }
        public void setRepassword(String repassword) {
            this.repassword = repassword;
        }
        public String getUrl() {
            return url;
        }
        public void setUrl(String url) {
            this.url = url;
        }
        public String getGender() {
            return gender;
        }
        public void setGender(String gender) {
            this.gender = gender;
        }
        public int getScore() {
            return score;
        }
        public void setScore(int score) {
            this.score = score;
        }
        
    }
    Student

      2)编写一个student.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%@ taglib uri="/struts-tags" prefix="s" %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
      </head>
      <body>
      <s:actionerror/>
      <%-- <s:fielderror />字段错误
      动作错误 --%>
      <%--struts2的form标签,它提供了和原始html表单标签几乎一致的属性
              action:请求地址。直接写动作名称。不用写contextPath
              method:请求方式。在这里可以不写,struts的form表单中默认是post
              enctype:表单编码的MIME类型
          
       --%>
      
      <s:form action="addStudent.action">
          <s:textfield  name="username" label="用户名" />
          <s:textfield  name="age" label="年龄" />
          <s:textfield  name="email" label="邮箱" />
          <s:textfield name="password" label="密码"/>
          <s:textfield name="repassword" label="确认密码"/>
          <s:textfield  name="score" label="成绩"/>
          <s:textfield  name="url" label="个人主页"/>
          <%--list中的取值是生成一个list集合,并往集合中放入元素 --%>
          <s:radio name="gender" list="{'男','女'}" label="性别"/>
          <s:submit value="注册"/>
      </s:form>
      </body>
    </html>
    student.jsp

      3)编写一个struts.xml,配置addStudent.action

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">
    <struts>
        <constant name="struts.devMode" value="true"></constant>
        <package name="p1" extends="struts-default">
            
            <!-- 声明式验证器的案例的动作类配置 -->
            <action name="addStudent" class="com.jxlg.web.action.StudentAction" method="addStudent">
                <result name="input">/student.jsp</result>
            </action>
        </package>
    </struts>
    struts.xml

      4)编写StudentAction动作类继承ActionSupport类和实现modelDriven接口

    package com.jxlg.web.action;
    
    import com.jxlg.domain.Student;
    import com.opensymphony.xwork2.ActionSupport;
    import com.opensymphony.xwork2.ModelDriven;
    
    public class StudentAction extends ActionSupport implements ModelDriven<Student> {
    
        private Student stu = new Student();
        public Student getModel() {
            return stu;
        }
        
        public String addStudent(){
            return SUCCESS;
        }
        public Student getStu() {
            return stu;
        }
        public void setStu(Student stu) {
            this.stu = stu;
        }
    
    }
    StudentAction

      5)编写UserAction-register-validation.xml来配置验证器

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE validators PUBLIC
              "-//Apache Struts//XWork Validator 1.0.3//EN"
              "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
    <validators>
        <field name="username">
            <field-validator type="requiredstring">
                <message>请正确输入用户名</message>
            </field-validator>
        </field>
        <field name="age">
            <field-validator type="int">
                <param name="min">18</param>
                <param name="max">100</param>
                <message>请输入18-100之间的整数</message>
            </field-validator>
        </field>
        <field name="email">
            <field-validator type="email">
                <message>请输入正确的邮箱格式</message>
            </field-validator>
        </field>
        <field name="password">
            <field-validator type="requiredstring">
            <!-- 注入取消使用trim -->
            <param name="trim">false</param>
                <message>请输入密码</message>
            </field-validator>
            <field-validator type="stringlength">
                <param name="minLength">3</param>
                <param name="maxLength">8</param>
                <message>请输入3-8位的密码</message>
            </field-validator>
        </field>
        
        <!-- 确认密码和密码必须保持一致,是2个字段的事情,所以要使用基于验证器的声明方式 -->
        <validator type="expression">
            <param name="expression">
            <!-- CDATA为了去掉特殊字符 -->
                <![CDATA[
                    password == repassword
                ]]>
            </param>
            <message>两次密码必须一致</message>
        </validator>
        <field name="score">
            <field-validator type="regex">
                <param name="regex">
                    /d+
                </param>
                <message>请正确输入成绩</message>
            </field-validator>
        </field>
        <field name="url">
            <field-validator type="url">
                <message>请正确输入url</message>
            </field-validator>
        </field>
        <field name="gender">
            <field-validator type="required">
                <!-- required是一个只验证是否为null的内置验证器,不去除空格 -->
                <message>请输入性别</message>
            </field-validator>
        </field>
    </validators>
    UserAction-register-validation.xml

      6)测试

        

      开发中的问题:

        1)在测试自己的student.jsp的页面中出现了错误  

          

          经过查看自己的score的标签中的name没有写导致的错误

        2)在测试密码和确认密码的时候发现不一致也不报错

          

          它属于动作错误,所以需要写上面的标签

          

     喜欢就推荐哦!

  • 相关阅读:
    git常用命令及多人协同开发及遇到的问题
    LightOJ
    LightOJ
    LightOJ
    LightOJ
    LightOJ
    LightOJ
    LightOJ
    LightOJ
    Codeforces Round #604 (Div. 2) E. Beautiful Mirrors
  • 原文地址:https://www.cnblogs.com/zhangyinhua/p/7776889.html
Copyright © 2011-2022 走看看