struts2(二)

来源:互联网 发布:成都英创 linux gpio 编辑:程序博客网 时间:2024/06/06 02:27

  • 封装请求参数
    • 动态参数注入请求参数用户输入的
      • 方式一动作类作为模型
      • 方式二动作类和模型分开
      • 方式三动作类和模型分开使用ModelDriven模型驱动
    • 静态参数注入
  • 自定义类型转换
    • 编写类型转换实现类
    • 声明定义配置
      • 局部类型转换器为某个类的某个属性字段进行验证
      • 全局转换器为某个类型进行验证
    • 转换失败之后的提示
  • 输入验证
    • 编程式验证
      • 针对所有方法进行验证
      • 针对指定的方法进行验证
        • 方式一
        • 方式二
    • 声明式验证
      • 针对所有方法进行验证
      • 针对指定的方法进行验证
      • struts2中提供的内置声明式验证器的使用
      • 自定义声明式验证
  • 自定义拦截器
    • 编写一个类继承AbstractInterceptor抽象类或者MethodFilterInterceptor抽象类
    • 声明定义与使用自定义拦截器

封装请求参数

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

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

  • 页面
<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