struts2(二)

封装请求参数

动态参数注入(请求参数,用户输入的)

方式一(动作类作为模型)

  • 页面
<form action="${pageContext.request.contextPath}/q1/login.do" method="post">
    <!-- name属性对应着动作类中的属性-->
    UserName:<input name="userName" type="text"/><br/>
    Password:<input name="password" type="password"/><br/>
    <input type="submit" value="登录"/>
</form>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 动作类
package com.jyh.action;

import com.opensymphony.xwork2.ActionSupport;

@SuppressWarnings("serial")
public class UserAction extends ActionSupport {

    //编写与表单里面名字相同的私有属性并提供相应的getset方法
    private String userName;
    private String password;
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getUserName() {
        return userName;
    }
    public String getPassword() {
        return password;
    }
    public String login(){
        System.out.println(userName + ":" + password);
        if("jyh".equals(userName) && "123".equals(password))
            return SUCCESS;
        return ERROR;
    }
}

   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

方式二(动作类和模型分开)

  • 页面
<form action="${pageContext.request.contextPath}/q2/login.do" method="post">
    <!-- name属性中person代表着动作类中模型对象的实例 -->
    UserName:<input name="person.userName" type="text"/><br/>
    Password:<input name="person.password" type="password"/><br/>
    <input type="submit" value="登录"/>
</form>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 动作类
package com.jyh.action;

import com.jyh.domain.Person;
import com.opensymphony.xwork2.ActionSupport;

@SuppressWarnings("serial")
public class PersonAction extends ActionSupport {

    private Person person = new Person();

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }
    public String login(){
        System.out.println(person);
        if("jyh".equals(person.getUserName()) && "123".equals(person.getPassword()))
            return SUCCESS;
        return ERROR;
    }
}

   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

方式三(动作类和模型分开,使用ModelDriven模型驱动)

  • 页面
<form action="${pageContext.request.contextPath}/q3/login.do" method="post">
    UserName:<input name="userName" type="text"/><br/>
    Password:<input name="password" type="password"/><br/>
    <input type="submit" value="登录"/>
</form>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5
  • 动作类
package com.jyh.action;

import com.jyh.domain.Person;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

@SuppressWarnings("serial")
public class PersonAction2 extends ActionSupport implements ModelDriven<Person>{

    private Person person = new Person();

    public String login(){
        System.out.println(person);
        if("jyh".equals(person.getUserName()) && "123".equals(person.getPassword()))
            return SUCCESS;
        return ERROR;
    }

    @Override
    public Person getModel() {
        return person;
    }
}

   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

模型就是JavaBean模型类,该功能是由modelDriven拦截器完成的,与struts2的值栈有关。

静态参数注入

就是在struts.xml配置文件中的action下面配置参数<param name="name">名字</param>
然后就给动作类对应的属性赋值了。

参数注入是由两个拦截器来完成。
静态参数注入:staticParams
动态参数注入:params

自定义类型转换

编写类型转换实现类

package com.jyh.convertors;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

import org.apache.struts2.util.StrutsTypeConverter;
//1、实现MM/dd/yyyy<------>java.util.Date互相转换
@SuppressWarnings("all")
public class MyDateConverter extends StrutsTypeConverter {

    private DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
    //String--->其他类型:Date
    /**
     * String[] values:用户输入的值.
     * Class toClass:目标类型
     */
    public Object convertFromString(Map context, String[] values, Class toClass) {
        if(toClass!=Date.class){
            throw new RuntimeException("您转换的不是日期,请选择别的转换器");
        }
        if(values==null||values.length==0)
            throw new IllegalArgumentException("没有数据");
        String sDate = values[0];//用户输入的是""
        if(!sDate.trim().equals("")){
            try {
                return df.parse(sDate);
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
        }
        return null;
    }
    //其他类型:Date---->String
    /**
     * Object o:对象
     */
    public String convertToString(Map context, Object o) {
        if(!(o instanceof Date)){
            throw new RuntimeException("您的数据不是日期,请选择别的转换器");
        }
        Date date = (Date)o;
        return df.format(date);
    }

}

   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

声明定义配置

局部类型转换器,为某个类的某个属性字段进行验证

  • 动作和模型分开
    配置文件放在模型类所在包,文件名为:模型类名-conversion.properties
    这里写图片描述
  • 动作和模型不分开
    配置文件放在动作类所在包,文件名为:动作类名-conversion.properties

全局转换器,为某个类型进行验证

配置文件放在构建路径顶端,文件名为:xwork-conversion.properties,里面一般是需要验证的类型对应自定义的转换器,比如Java.util.Date=com.jyh.convertors.MyDateConverter。

转换失败之后的提示

  1. 转换失败,会自动转到一个name=input的逻辑视图,一般指向输入的那个页面,目的回显(建议使用struts2的表单标签)
  2. 错误消息提示中文版本
    前提:动作类继承ActionSupport才能使用。
    文件名为:类名.properties
    这里写图片描述

总结就是转换器配置文件名为:需要验证的属性所在类的类名-conversion.properties
中文提示信息的配置文件名为:被验证的属性所在类的类名.properties

输入验证

编程式验证

缺点:验证规则写到了代码中,硬编码。
优点:验证时可以控制的更加精细。(用的少)

针对所有方法进行验证

1.动作类需要实现ActionSupport,覆盖掉public void validate(){}方法,
2.方法内部:编写你的验证规则,不正确的情况调用addFieldError添加错误信息

public void validate() {
    if("".equals(student.getUsername())){
        addFieldError("username", "请输入用户名");
    }
}
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

使用username这种方式添加错误信息s:fieldError标签中和普通标签中都有错误提示消息,使用了,将只会在s:fieldError中显示错误消息
3.验证失败:
视图:会自动转向一个name=input的逻辑视图
错误消息提示:建议使用struts2标签库。如果没有显示请使用s:fieldError标签

针对指定的方法进行验证

方式一

在指定方法前面添加一个注解:@SkipValidation,有该注解的方法就不会进行验证

方式二

在需要验证的方法,编写一个方法,命名为validate+需要验证的方法名,需要验证的方法名首字母需要大写,如:如果一个动作方法名叫做regist,只针对该方法进行验证,就编写public void validateRegist(){};
这里写图片描述

声明式验证

优点:把验证规则写到了配置文件中。(用得多)
缺点:不是很精细。
错误视图和消息提示和编程式一致。

针对所有方法进行验证

在动作类所在的包中建立:动作类名-validation.xml配置文件。
头部声明可以在struts包/xwork-core-xxx.jar/xwork-validator-xxx.dtd中找到,该dtd文件就是验证配置文件的约束。

针对指定的方法进行验证

文件名改为:动作类名-动作名(struts.xml中action的name属性)-validation.xml

说明:验证功能是由validation拦截器来负责处理的。回显错误信息是由workflow拦截器来负责处理的。

struts2中提供的内置声明式验证器的使用

Struts2提供的声明式验证器在xwork-core-**.jar包的
com.opensymphony.xwork2.validator.validators.default.xml配置文件中。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
        "-//Apache Struts//XWork Validator Definition 1.0//EN"
        "http://struts.apache.org/dtds/xwork-validator-definition-1.0.dtd">

<!-- START SNIPPET: validators-default -->
<validators>
    <validator name="required" class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/>
    <validator name="requiredstring" class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/>
    <validator name="int" class="com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator"/>
    <validator name="long" class="com.opensymphony.xwork2.validator.validators.LongRangeFieldValidator"/>
    <validator name="short" class="com.opensymphony.xwork2.validator.validators.ShortRangeFieldValidator"/>
    <validator name="double" class="com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator"/>
    <validator name="date" class="com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator"/>
    <validator name="expression" class="com.opensymphony.xwork2.validator.validators.ExpressionValidator"/>
    <validator name="fieldexpression" class="com.opensymphony.xwork2.validator.validators.FieldExpressionValidator"/>
    <validator name="email" class="com.opensymphony.xwork2.validator.validators.EmailValidator"/>
    <validator name="url" class="com.opensymphony.xwork2.validator.validators.URLValidator"/>
    <validator name="visitor" class="com.opensymphony.xwork2.validator.validators.VisitorFieldValidator"/>
    <validator name="conversion" class="com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator"/>
    <validator name="stringlength" class="com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator"/>
    <validator name="regex" class="com.opensymphony.xwork2.validator.validators.RegexFieldValidator"/>
    <validator name="conditionalvisitor" class="com.opensymphony.xwork2.validator.validators.ConditionalVisitorFieldValidator"/>
</validators>
<!--  END SNIPPET: validators-default -->

   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

验证配置文件写法:

<?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是字段名。和表单一致 -->
    <field name="username">
        <!-- 必须由3~8位字母组成-->
        <field-validator type="regex"><!-- type为验证类型,也就是验证器的名字 -->
            <param name="regexExpression"><![CDATA[[a-zA-Z]{3,8}]]></param><!-- param是指定验证器的属性参数 -->
             <message>你的名字必须由3~8位字母组成</message><!-- message是返回的错误信息 -->
        </field-validator>
    </field>
    <!-- 验证密码必须3~8位数字组成:换一种 -->
    <!-- 
    <validator type="regex">
        <param name="fieldName">password</param>
        <param name="regexExpression"><![CDATA[\d{3,8}]]></param>
         <message>你的密码必须由3~8位数字组成</message>
    </validator>
     -->
     <field name="password">
        <field-validator type="requiredstring">
            <message>请输入密码</message>
        </field-validator>
        <field-validator type="strongpassword">
            <message>你的密码必须由大小写字母和数字组成</message>
        </field-validator>
     </field>
    <!-- 必须选择性别 -->
    <field name="gender">
        <field-validator type="required">
             <message>请选择性别</message>
        </field-validator>
    </field>
    <field name="email">
        <field-validator type="email">
             <message>请输入正确的邮箱</message>
        </field-validator>
    </field>
</validators>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

自定义声明式验证

验证密码的强度:至少一个大写、小写、数字组成。
这里写图片描述
1.验证的实现:编写一个类,继承FieldValidatorSupport。

package com.jyh.validators;
import com.opensymphony.xwork2.validator.ValidationException;
import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport;

public class StrongPasswordValidator extends FieldValidatorSupport {
    private boolean trim = true;

    public boolean isTrim() {
        return trim;
    }

    public void setTrim(boolean trim) {
        this.trim = trim;
    }

    // Object object:当前执行的动作类
    public void validate(Object object) throws ValidationException {
        String fieldName = getFieldName();// 当前要验证的字段名
        Object value = this.getFieldValue(fieldName, object);// 获取用户输入的值
        if (!(value instanceof String)) {
            addFieldError(fieldName, object);
        } else {
            String s = (String) value;

            if (trim) {
                s = s.trim();
            }

            if (!isPasswordStrong(s)) {
                addFieldError(fieldName, object);
            }
        }
    }

    private static final String GROUP1 = "abcdefghijklmnopqrstuvwxyz";
    private static final String GROUP2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final String GROUP3 = "0123456789";

    protected boolean isPasswordStrong(String password) {
        boolean ok1 = false;
        boolean ok2 = false;
        boolean ok3 = false;
        int length = password.length();
        for (int i = 0; i < length; i++) {
            if (ok1 && ok2 && ok3)
                break;
            String character = password.substring(i, i + 1);
            if (GROUP1.contains(character)) {
                ok1 = true;
                continue;
            }
            if (GROUP2.contains(character)) {
                ok2 = true;
                continue;
            }
            if (GROUP3.contains(character)) {
                ok3 = true;
                continue;
            }
        }
        return ok1 && ok2 && ok3;
    }
}

   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

2.验证的声明:在构建路径顶端,建立一个固定名称为validators.xml的配置文件,配置文件参考
xwork-core-xxx.jar包的com.opensymphony.xwork2.validator.validators.default.xml。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
        "-//Apache Struts//XWork Validator Definition 1.0//EN"
        "http://struts.apache.org/dtds/xwork-validator-definition-1.0.dtd">
<validators>
    <!-- name为验证器的名字,class为验证器的实现类 -->
    <validator name="strongpassword" class="com.jyh.validators.StrongPasswordValidator"/>
</validators>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

3.验证器的使用

<field name="password">
        <field-validator type="requiredstring">
            <message>请输入密码</message>
        </field-validator>
        <!-- type为验证器的name属性 -->
        <field-validator type="strongpassword">
            <message>你的密码必须由大小写字母和数字组成</message>
        </field-validator>
     </field>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

自定义拦截器

编写一个类,继承AbstractInterceptor抽象类或者MethodFilterInterceptor抽象类

package com.jyh.interceptors;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;

@SuppressWarnings("serial")
//继承MethodFilterInterceptor可以有选择的进行拦截与不拦截
public class Demo1Interceptor extends MethodFilterInterceptor/*AbstractInterceptor*/{

    public String doIntercept(ActionInvocation invocation) throws Exception {
        System.out.println("拦截前");
        String valueString = invocation.invoke();//放行
        System.out.println("拦截后");
        return valueString;
    }

}

   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

声明定义与使用自定义拦截器

 <!-- 定义一个包,用来进行拦截器的定义初始化 -->
    <package name="myDefaultPackage" extends="struts-default">
        <!-- 声明定义拦截器 -->
        <interceptors>
            <!-- 拦截器名和其实现类 -->
            <interceptor name="demo1Interceptor" class="com.jyh.interceptors.Demo1Interceptor"></interceptor>
            <!-- 定义一个拦截器栈 -->
            <interceptor-stack name="mydefault">
                <!-- 包含默认的defaultStack栈 -->
                <interceptor-ref name="defaultStack"></interceptor-ref>
                <!-- 包含自己定义的拦截器 -->
                <interceptor-ref name="demo1Interceptor"></interceptor-ref>
            </interceptor-stack>
        </interceptors>

        <!-- 覆盖默认的拦截器栈 -->
        <default-interceptor-ref name="mydefault"></default-interceptor-ref>
    </package>

    <!-- 继承刚刚定义的包 -->
    <package name="demo" extends="myDefaultPackage" namespace="/demo">
        <action name="demo1" class="com.jyh.action.Demo1Action" method="add">
            <!-- 使用拦截器,将会 覆盖所有默认拦截器 -->
            <interceptor-ref name="demo1Interceptor">
                <!-- 添加参数excludeMethods代表不拦截,后面为不拦截的方法名(当前访问的方法名)
                includeMethods代表拦截 -->
                <param name="excludeMethods">add</param>
            </interceptor-ref>
            <result name="success">/demo1.jsp</result>
        </action>

        <action name="demo2" class="com.jyh.action.Demo1Action" method="del">
            <!-- 使用拦截器栈,将会 覆盖所有默认拦截器,但是因为继承了默认的拦截器栈,所以保存了默认的拦截器 -->
            <interceptor-ref name="mydefault"></interceptor-ref>
            <result name="success">/demo1.jsp</result>
        </action>
    </package>

转自:http://blog.csdn.net/Nicorui/article/details/54585942

猜你喜欢

转载自blog.csdn.net/liuyi6/article/details/74909566
今日推荐