您的位置:首页 > 编程语言 > Java开发

Struts2学习之2(请求参数的封装,类型转换,输入验证,自定义拦截器)

2017-01-17 19:24 871 查看

封装请求参数

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

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

页面

<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>


动作类

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;
}
}


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

页面

<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>


动作类

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;
}
}


方式三(动作类和模型分开,使用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>


动作类

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;
}
}


模型就是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);
}

}


声明定义配置

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

动作和模型分开

配置文件放在模型类所在包,文件名为:模型类名-conversion.properties



动作和模型不分开

配置文件放在动作类所在包,文件名为:动作类名-conversion.properties

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

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

转换失败之后的提示

转换失败,会自动转到一个name=input的逻辑视图,一般指向输入的那个页面,目的回显(建议使用struts2的表单标签)

错误消息提示中文版本

前提:动作类继承ActionSupport才能使用。

文件名为:类名.properties



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

中文提示信息的配置文件名为:被验证的属性所在类的类名.properties

输入验证

编程式验证

缺点:验证规则写到了代码中,硬编码。

优点:验证时可以控制的更加精细。(用的少)

针对所有方法进行验证

1.动作类需要实现ActionSupport,覆盖掉public void validate(){}方法,

2.方法内部:编写你的验证规则,不正确的情况调用addFieldError添加错误信息

public void validate() {
if("".equals(student.getUsername())){
addFieldError("username", "请输入用户名");
}
}


使用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.StringLengthFi
fafa
eldValidator"/>
<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 -->


验证配置文件写法:

<?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.验证的实现:编写一个类,继承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;
}
}


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>


3.验证器的使用

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


自定义拦截器

编写一个类,继承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;
}

}


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

<!-- 定义一个包,用来进行拦截器的定义初始化 -->
<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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java web java struts2
相关文章推荐