struts2校验总结

    技术2022-05-19  21

    六. 输入校验     1. 为什么需要输入校验?        对于一个Web应用而言,所有的用户数据都是通过浏览器收集的,用户的输入信息是非常复杂的:用户操作不熟练,输入出错,        硬件设备的不正常,网络传输的不稳定,甚至有恶意的蓄意破坏..., 这些都有可能导致输入异常;               输入的异常,轻则导致系统非正常中断,重则导致系统崩溃。应用程序必须能正常处理。对异常输入的过滤,就是输入校验,也        称为数据校验;通常的做法是碰到异常输入时应用程序直接返回,提示浏览者必须重新输入。        输入校验分为客户端校验和服务器校验,客户端校验主要是过滤正常用户的误操作,主要通过JavaScript代码完成;服务器端校        验是整个应用阻止非法数据的最后防线,主要通过在应用中编程实现。        Struts2提供了非常强大的输入校验体系,通过Struts2内建的输入校验器,Struts2应用无需书写任何输入校验代码,即可完成绝        大部分输入校验,并可以同时完成客户端校验和服务器端校验。当然, Struts2也允许客户自行提供校验器。     2. 服务器端校验        1) 手动校验           步骤:a. action继承ActionSupport, 重写方法                    public void validate(){...}                    如果出现错误,调用ActionSupport中所提供的addFieldError("提示内容key","提示内容")方法加入错误提示;                           b. 在 struts.xml 文件中 action 中配置名称为 input 的 result, 用以显示错误信息;                 c. 在名称为 input 的result对应的JSP页面,通过标记<s:fielderror/>显示错误信息;                    <s:fielderror/>             ->  显示所有错误信息;                      <s:fielderror>                        <s:param>消息提示名称</s:param>                    </s:fielderror>           输入校验流程:           a. 类型转换器负责对字符串的请求参数执行类型转换,并将这些值设置成Action的属性值;           b. 在执行转换过程中可能出现异常,如果出现异常,将异常信息保存到ActionContext中,conversionError拦截器负责将其              封装到fieldError里,然后执行步骤3;如果转换过程中没有异常信息,则直接进入第3步;           c. 通过反射调用validateXxx()方法,其中Xxx是即将处理用户请求的处理逻辑所对应的方法名;           d. 调用Action类里的validate()方法;           e. 如果经过上面4步都没有出现fieldError,将调用Action里处理用户请求的处理方法,如果出现了fieldError, 系统将转入              input逻辑视图所指定的视图逻辑;        2) Xwork验证框架           正如你所见,当你不同的用例需要不同的验证规则时,手动验证使你的代码显得很混乱;依然要写很多代码,编程依然很烦琐,           代码复用不高。 Struts2提供了基于验证框架的输入校验,在这种校验方式下,所有的输入校验只需要通过指定简单的配置           文件即可。           采用框架验证与手动验证步骤基本相同,只不过第一步Action中无须重写validate()方法;           a. 构建 *-validation.xml 文件              采用Struts2的校验框架时,只需要为该Action指定一个校验文件即可。校验文件是一个XML配置文件,每一个Action都有一个              校验文件,该文件的文件名应用遵守如下规则:              <Action名字>-validation.xml              该文件应该被保存在与Action class 文件相同的路径下,便于管理。              增加了该校验文件后,其他部分无需任何修改,系统自动会加载该文件,当用户提交请求时,Struts2的校验框架会根据该              文件对用户请求进行校验。           b. 注册验证器              验证器也是一个Java类,一个实现了com.opensymphony.xwork.validator.Validator接口的类;              但验证器写好后必须注册,通过注册给该验证器指定一个逻辑名,以方便Struts2程序对该验证器的访问;              注册有二种方式:              i.  通过ValidatorFactory类编码注册:                  通过调用类com.opensymphony.xwork.validator.ValidatorFactory类中静态方法                  void registerValidator(String name, Class c);                  实现。              ii. 通过校验器注册文件配置注册:                              在classpath根路径下提供一个validators.xml文件,通过该文件进行配置;这个文件称之为校验器注册文件;                  Struts2提供了大量的校验器,这些内建的校验器可以满足大部分应用的校验需求。这些内建的校验器也需                  注册,它们采用了配置注册方式,校验器文件位于 xwork-2.0.1.jar 文件中 com/opensymphony/xwork2/validator/                  validators/ 目录下,一个名为 default.xml 文件中。该文件就是 Struts2的默认校验器注册文件。           c. 内建校验器              . required: 必填校验器,要求指定字段必须有值;              . requiredstring: 必填字符器校验器,要求字段值必须非空且长度大于0;                i. trim:  是否在校验前截断被校验属性值前后的空白,该属性是可选的,默认是 true.              . stringlength: 字符串长度校验器, 要求校验字符长度必须在指定范围;                i.  trim:  是否在校验前截断被校验属性值前后的空白,该属性是可选的,默认是 true.                ii. minLength: 指定字段值的最小长度,可选,不指定则最小长度不受限制;                iii.maxLength: 指定字段值的最大长度,可选,不指定则最大长度不受限制;              . int: 整数验校器,要求校验字段的整数值必须在指定范围内;                i.  min: 指定该属性最小值,如不指定,则不检查最小值;                ii. max: 指定该属性最大值,如不指定,则不检查最大值;              . double: 浮点数验校器,要求校验字段的双精度浮点数值必须在指定范围内;              . date: 日期验校器,要求校验字段的日期值必须在指定范围内;                i.  min: 指定该属性最小值,如不指定,则不检查最小值;示例:<param name="min">1990-01-01</param>                ii. max: 指定该属性最大值,如不指定,则不检查最大值;              . email: 邮件地址校验器,它要求被检查字段的字符如果非空,则必须是合法的邮件地址;它基于正则表达式进行校验;              . url: 网址校验器,它要求被检查字段字符如果非空,则必须是合法的URL地址;它基于正则表达式进行校验;              . conversion: 检查被校验字段在类型转换过程中是否出现错误。                i.  fieldName: 指定校验的 Action 属性名,如采用字段校验器风格,则无须指定该参数;                ii. repopulateField: 类型转换失败,返回 input 页面时,类型转换失败的表单域是否保留原来的错误输入。              . expression_r: 表达式校验器,非字段校验器,它会按OGNL语法指定一个返回boolean类型值的表达式。当返回 true,                     校验通过;该逻辑表达式基于 ValueStack 进行求值;                <validators>                     <validator type="expression_r">                           <param name="expression_r">...</param>                           <message>Failed to meet Ognl expression_r ...</message>                     </validator>                </validators>              . visitor: 验证Action里的复合属性(自定义类型);                i.  context: 指定校验规则文件的context            ii. appendPrefix: 指定校验失败后提示信息是否添加前缀                示例:                i. StudentAction-validation.xml                   -----------------------------------------                   <field name="student">                       <field-validator type="visitor">                     <param name="context">studentContext</param>                  <param name="appendPrefix">true</param>                  <message>STUDENT:</message>                 </field-validator>           </field>                ii. Student-studentContext-validation.xml                    -----------------------------------------                  <field name="name">             <field-validator type="requiredstring">                 <param name="trim">true</param>                 <message>PLEASE input your name!</message>             </field-validator>            </field>            <field name="age">             <field-validator type="int">                 <param name="min">1</param>                 <param name="max">100</param>                 <message>AGE must be between ${min} and ${max}!</message>             </field-validator>            </field>                                                    iii. 错误页面显示:                     -----------------------------------------                                       STUDENT: PLEASE input your name!                     STUDENT: AGE must be between 1 and 100!                                 . fieldexpression_r: 功能类同于 expression_r, 适合于字段校验器,要求指定 fileName 要求校验的Action的属性名;                <validators>                     <validator type="expression_r">                           <param name="fileName">name</param>                           <param name="expression_r">...</param>                           <message>Failed to meet Ognl expression_r ...</message>                     </validator>                </validators>              . regex: 检查被校验字段是否匹配一个正则表达式;                i.  fieldName: 指定校验的Action属性名;                ii. expression_r: 指定正则表达式                iii.caseSensitive: 指定正则表达式匹配时,是否区分大小写,默认值为 true;        3) 探索高级功能           a. 自定义验证器              步骤一:实现接口Validator或继承类FieldValidatorSupport              步骤二:在验证器中提供与参数同名的属性以及对应的setter/getter方法,重写valide()方法         public class MyValidator extends FieldValidatorSupport {             private String validName="";                         public void validate(Object arg0) throws ValidationException {                 String fieldName=this.getFieldName();                 String fieldValue=(String)this.getFieldValue(fieldName, arg0);                 if(validName.indexOf(fieldValue.trim().toLowerCase())!=-1) return;                 addFieldError(fieldName,arg0);                    }             public String getValidName() {                 return validName;             }             public void setValidName(String validName) {                 this.validName = validName.toLowerCase();             }         }              步骤三:在classpath中配置文件 validators.xml             <validators>                 <validator name="validName" class="com.briup.MyValidator"/>             </validators>              步骤四:在验证文件中使用自定义验证器         <field-validator type="validName">             <param name="validName">zs,ls,ww</param>             <message>Invalid name, please try again!</message>         </field-validator>                                  b. 使用OGNL表达式语言无须写Java代码构建验证规则        4) 使用不同的context进行验证           一个Action可以处理多个请求,不同请求有不同的验证规则,可以使用不同的验证文件封装不同的验证规则;           1) struts.xml文件中:                  <action name="studentLogin" class="com.briup.StudentAction" method="login">             <result name="success">/studentResult.jsp</result>             <result name="input">/studentLogin.jsp</result>         </action>           2) 验证文件应与Action同一个目录,名称应为 Action类名-action逻辑名-validation.xml        5) Short-circuiting验证           一个字段如果设置有多个验证器,多个验证器都会生效。从而显示多个错误提示。如果想在前面验证器验证           失败后后面验证器就不参与验证,可在前面验证器上显示设置属性short-circuit值为"true", 其默认值为           false. 示例:           <field name="name">              <field-validator type="stringlength" short-circuit="true">             <param name="minLength">1</param>             <param name="maxLength">10</param>                 <message>Length must be between 1 and 10!</message>              </field-validator>                     <field-validator type="validName">             <param name="validName">zs,ls,ww</param>                 <message>Invalid name, please try again!</message>              </field-validator>       </field>           上述例子上name表单控件值如果长度不符,则validName类型的验证器不会被调用。           另 requiredstring 名称的验证器类型设置short-circuit="true"对后续验证器不起作用。        5) expression_rValidator验证                         使用OGNL表达式作为验证条件,示例:           <validators>           <validator type="expression_r">          <param name="expression_r">name.equals("ls")</param>          <message>INVALID NAME!</message>           </validator>               <field name="name">                  <field-validator type="requiredstring">                  <message>Name is required!</message>               </field-validator>           </validators>            上述例子中 name 为一属性名,使用expression_r验证器验证其值是否为 "ls". 其中"ls"为一个具体值直接写在           验证配置文件中,也可以来自静态常量或静态方法的返回值。示例:           <validators>           <validator type="expression_r">          <param name="expression_r">name.equals(@com.briup.Constant@NAME)</param>          <message>INVALID NAME!</message>           </validator>                    </validators>            其中Constant类源文件为:       public class Constant {           public static final String NAME="ww";           public static String getName() {               return "sq";           }       }           注意:属性和方法的修饰符应设置为 public.        5) VisitorFieldValidator验证           多个Action类中都要验证相同JavaBean对象的各个属性,为了避免验证配置信息出现在多个配置文件中,可以           将JavaBean对象的验证信息单独写在一个文件中,然后各Action验证配置文件使用visitor类型验证器去引用。           示例:           a. 没有使用visitor类型验证器              i.  JSP页面                  login.jsp                  ---------------------------------------------------------------                  <h3>Student Login</h3>                  <s:form action="login">                      <s:textfield name="name" label="name"/>                      <s:textfield name="password" label="Password"/>                      <s:submit value="Submit"/>                  </s:form>                  register.jsp                  ---------------------------------------------------------------                  <h3>Student Register</h3>                  <s:form action="register">                      <s:textfield name="name" label="name"/>                      <s:textfield name="password" label="Password"/>                      <s:submit value="Submit"/>                  </s:form>              ii. Action          StudentProAction.java                  ---------------------------------------------------------------                  public class StudentProAction extends                      ActionSupport implements ModelDriven<Student> {                      private Student student=new Student();                                           public String login() {                          return "success";                      }                                       public String register() {                          return "success";                      }                          public Student getModel() {                          return student;                      }                  }              iii.Struts.xml         <action name="login" class="com.briup.StudentProAction" method="login">             <result>/loginResult.jsp</result>             <result name="input">/login.jsp</result>         </action>         <action name="register" class="com.briup.StudentProAction" method="register">             <result>/registerResult.jsp</result>             <result name="input">/register.jsp</result>         </action>              iii.验证配置文件:                  StudentProAction-login-validation.xml(和StudentProAction同包)                  ---------------------------------------------------------------         <validators>             <field name="name">   <!-- 属性名应与表单控件同名,而不是Action中属性名-->                 <field-validator type="requiredstring">                     <message>Name is required!</message>                 </field-validator>             </field>             <field name="password">                 <field-validator type="requiredstring">                     <message>Password is required!</message>                 </field-validator>             </field>            </validators>                  StudentProAction-register-validation.xml(和StudentProAction同包)                  ---------------------------------------------------------------         <validators>             <field name="name">                 <field-validator type="requiredstring">                     <message>Name is required!</message>                 </field-validator>             </field>             <field name="password">                 <field-validator type="requiredstring">                     <message>Password is required!</message>                 </field-validator>             </field>            </validators>         注意:验证配置文件中<field>中name属性值与表单控制同名,使用<s:textfield>即可显示错误提示信息,                       否则,须通过<s:fielderror/>显示错误提示信息;                       . <s:fielderror/>:显示所有field级别的错误提示信息;                       . <s:fielderror>                    <s:param>student.password</s:param>                     </s:fielderror>                         : 提定显示名称为student.password的field级别的错误提示信息;           b. 使用visitor类型验证器              其它地方与上同,只是配置文件和显示错误信息设置有点变动:              iii.验证配置文件:                  StudentProAction-login-validation.xml(和StudentProAction同包)                  ---------------------------------------------------------------         <validators>             <field name="student">   <!-- 属性名与Action中属性同名-->                 <field-validator type="requiredstring">                     <message>Name is required!</message>                 </field-validator>             </field>         </validators>                  StudentProAction-register-validation.xml(和StudentProAction同包)                  ---------------------------------------------------------------         <validators>             <field name="student">   <!-- 属性名与Action中属性同名-->                 <field-validator type="requiredstring">                     <message>Name is required!</message>                 </field-validator>             </field>         </validators>                  Student-validation.xml(和Student类同包)                  ---------------------------------------------------------------         <validators>             <field name="name">                 <field-validator type="requiredstring">                     <message>Name is required!</message>                 </field-validator>             </field>             <field name="password">                 <field-validator type="requiredstring">                     <message>Password is required!</message>                 </field-validator>             </field>            </validators>                 注意这时显示错误信息时须使用标记 <s:fielderror/>.     2. 客户端校验             在服务器端设置成功的基础上,在<s:form>标记中将属性validate设置为true即可。这时错误显示效果和服务器端        验证相同,只不过借助于javascript实现而已。        注意,借助于OGNL表达式使用expression_r类型的验证器还需使用服务器端验证实现。???        七. 国际化     1. JSP页面显示国际化信息:          <s:text name="login.title"/>            <!-- login.title为资源文件key值 -->        <s:textfield name="name" key="login.name"/>    <!-- login.name为资源文件key值 -->        <s:property value="%{getText('login.name')}"/>   <!-- login.name为资源文件key值 -->            2. Action中获取国际化信息        getText("资源文件key值");                        //getText为ActionSupport的方法     3. 配置文件中获取国际化信息        <message>${getText('login.name')</message>       <!-- login.name为资源文件key值 -->

     


    最新回复(0)