当前位置:文档之家› Struts 2讲义 (5)

Struts 2讲义 (5)

Struts 2 讲义(5)

--Struts2特性

一、国际化

国际化的步骤:

1)建立一个中文资源文件,globalMessages.properties。用文本编辑器输入,内容如下:

#定义国际化资源文件

HelloWorld=你好,世界!

name=用户名称

pass=用户密码

username=用户名

password1=密码

password2=确认密码

birthday=生日

2)在Dos中执行下面命令:

native2ascii globalMessages.properties

globalMessages_zh_CN.properties

3)中文资源文件名:globalMessages_zh_CN.properties。转换内容为:

#\u5b9a\u4e49\u56fd\u9645\u5316\u8d44\u6e90\u6587\u4ef6

HelloWorld=\u4f60\u597d\uff0c\u4e16\u754c\uff01

name=\u7528\u6237\u540d\u79f0

pass=\u7528\u6237\u5bc6\u7801

username=\u7528\u6237\u540d

password1=\u5bc6\u7801

password2=\u786e\u8ba4\u5bc6\u7801

birthday=\u751f\u65e5

4)建立一个英文资源文件内容为:globalMessages_en_US.properties HelloWorld=Hell World!

name=username

pass=password

username=Your Name

password1=Password

password2=confirm Password

birthday=Birthday

5)上述两个文件保存到WEB-INF\classes目录中

6)创建struts.properties 中,保存到WEB-INF\classes目录下,内容如下:

struts.custom.i18n.resources=globalMessages

7)创建reg.jsp

<%@ page language="java" pageEncoding="UTF-8"%>

<%@ taglib prefix="s" uri="/struts-tags" %>

UI Tags Example

8)创建reg_ok_local.jsp代码如下所示:

<%@ page language="java" pageEncoding="UTF-8"%>

<%@ taglib prefix="s" uri="/struts-tags" %>

注册成功

欢迎注册成功!

9)创建Reg.java

p ackage com.my.inter;

import java.util.Date;

import com.opensymphony.xwork2.Action;

public class Reg implements Action {

private String username;

private String password1;

private String password2;

private Date birthday;

public Reg(){

}

public String getUsername() {

return username;

}

public void setUsername(String username) { https://www.doczj.com/doc/a13203606.html,ername = username;

}

public String getPassword1() {

return password1;

}

public void setPassword1(String password1) { this.password1 = password1;

}

public String getPassword2() {

return password2;

}

public void setPassword2(String password2) { this.password2 = password2;

}

public Date getBirthday() {

return birthday;

}

public void setBirthday(Date birthday) { this.birthday = birthday;

}

public String execute() throws Exception {

return SUCCESS;

}

}

9)配置struts.xml

/reg_ok_local.jsp

执行结果如下:

改进reg_tag.jsp

Struts2 可以在label值中访问国际化资源文件。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags" %>

UI Tags Example

运行结果如下图所示:

二、数据校验

1.输入校验简介

在Web 系统项目中有大量的视图页面需要用户自行输入很多数据。这些数据的类型有很多种。为了防止某些客户的恶意输入以及对Web 项目的恶意破坏。必须引入输入校验像Windows 操作系统中的防火墙一样把一些“垃圾”数据过滤,挡在Web 系统之外。Struts2 的输入校验是以类型转换为基础。而且输入校验一般和Web 系统的业务逻辑息息相关。

1.使用validate方法进行校验

Struts2 对输入校验这方面采用的最基本方法是在每个Action 里继承ActionSupport 类,并且重写它的输入校验方法validate()。在注册页面中输入各种校验将所有不符合输入校验规则的错误信息都由ActionSupport 类中另一个方法addFieldError 方法将错误信息加入到表单错误信息,并且在输入数据的页面显示,而不会再由Action 导航到注册成功页面。【例3-4】使用validate方法进行校验实例。

⑴注册页面:register.jsp

<%@ page language="java" pageEncoding="gb2312"%>

<%@ taglib prefix="s" uri="/struts-tags"%>

注册页面

⑵注册控制类:RegisterAction.java

package https://www.doczj.com/doc/a13203606.html,it;

import com.opensymphony.xwork2.ActionSupport;

import java.util.Date;

public class RegisterAction extends ActionSupport {

// Action类公用私有变量,用来做页面导航标志

private static String FORWARD = null;

private String username; // 用户名属性

private String password; // 密码属性

private String repassword; // 确认密码属性

private Date birthday; // 生日属性

private String mobile; // 手机号码属性

private int age; // 年龄属性

public String getUsername() { // 取得用户名值

return username;

}

public void setUsername(String username) { // 设置用户名值

https://www.doczj.com/doc/a13203606.html,ername = username;

}

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 Date getBirthday() { // 取得生日值

return birthday;

}

public void setBirthday(Date birthday) { // 设置生日值

this.birthday = birthday;

}

public String getMobile() { // 取得手机号码值

return mobile;

}

public void setMobile(String mobile) { // 设置手机号码值

this.mobile = mobile;

}

public int getAge() { // 取得年龄值

return age;

}

public void setAge(int age) { // 设置年龄值

this.age = age;

}

public String execute() throws Exception { // 执行注册方法FORWARD = "success";

return FORWARD;

}

public void validate() { // 校验方法,用来输入校验

// 校验是否输入用户名

if (getUsername() == null || getUsername().trim().equals("")) { addFieldError("username", "请输入用户名");

}

// 校验是否输入生日

if(getBirthday()==null){

addFieldError("birthday", "请输入生日日期");

}else

// 校验是否输入正确的生日日期

if(getBirthday().after(new Date())){

addFieldError("birthday", "请不要输入未来日期");

}

// 校验是否输入密码

if (getPassword() == null || getPassword().trim().equals("")) { addFieldError("password", "请输入密码");

}

// 校验是否输入确认密码

if (getRepassword() == null || getRepassword().trim().equals("")) { addFieldError("repassword", "请输入确认密码");

}

// 校验输入的密码和确认密码是否一致

if (!getPassword().equals(getRepassword())) {

addFieldError("repassword", "确认密码和密码输入不一致");

}

// 校验输入的手机号码长度是否正确

if (getMobile().length()!=11) {

addFieldError("mobile", "请输入正确的手机号码");

}

// 校验输入的年龄是否正确

if (getAge()<1||getAge()>99) {

addFieldError("age", "请输入您的真实年龄");

}

}

}

⑶注册成功页面:register1.jsp

<%@ page language="java" pageEncoding="gb2312"%>

<%@ taglib prefix="s" uri="/struts-tags"%>

注册页面

运行结果如图3-8、3-9所示。

图3-8没有输入数据校验

图3-9 校验输入密码不一致

2.使用validateXXX方法进行校验

Struts2 中除了validate 方法之外它还有一种validateXXX 方法针对Action 中某一特定方法进行各种字段的输入校验。其中XXX 就是该特定方法名。

【注】:如果使用validateRegister 方法,那最好不要再使用validate 方法。validate 方法是对所有Action 中方法的输入校验都进行校验,validateRegister 方法只对Register 方法进行校验。因此两者不能重复使用,都使用会造成两个方法都进行了校验的结果。执行顺序是先

validateRegister后validate。如果validateRegister 方法有特殊的输入校验则就会被validate 方法“覆盖”,因此达不到预期的输入校验目的。

【例3-5】使用validateXXX方法进行校验实例。

⑴注册页面:register1.jsp

<%@ page language="java" pageEncoding="gb2312"%>

<%@taglib prefix="s" uri="/struts-tags"%>

注册页面

⑵注册控制类:RegisterAction1.java

package https://www.doczj.com/doc/a13203606.html,it;

import java.util.Date;

import com.opensymphony.xwork2.ActionSupport;

public class RegisterAction1 extends ActionSupport {

private static String FORWARD = null;

private String username; // 用户名属性

private String password; // 密码属性

private String repassword; // 确认密码属性

private Date birthday; // 生日属性

private String mobile; // 手机号码属性

private int age; // 年龄属性

public String getUsername() { // 取得用户名值

return username;

}

public void setUsername(String username) { // 设置用户名值

https://www.doczj.com/doc/a13203606.html,ername = username;

}

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 Date getBirthday() { // 取得生日值

return birthday;

}

public void setBirthday(Date birthday) { // 设置生日值

this.birthday = birthday;

}

public String getMobile() { // 取得手机号码值

return mobile;

}

public void setMobile(String mobile) { // 设置手机号码值this.mobile = mobile;

}

public int getAge() { // 取得年龄值

return age;

}

public void setAge(int age) { // 设置年龄值

this.age = age;

}

// 执行注册方法

public String Register() throws Exception {

FORWARD = "success";

return FORWARD;

}

public void validateRegister() { // 校验方法,用来输入校验// 校验是否输入用户名

if (getUsername() == null || getUsername().trim().equals("")) { addFieldError("username", "请输入用户名");

}

// 校验是否输入生日

if (getBirthday() == null) {

addFieldError("birthday", "请输入生日日期");

} else

// 校验是否输入正确的生日日期

if (getBirthday().after(new Date())) {

addFieldError("birthday", "请不要输入未来日期");

}

// 校验是否输入密码

if (getPassword() == null || getPassword().trim().equals("")) { addFieldError("password", "请输入密码");

}

// 校验是否输入确认密码

if (getRepassword() == null || getRepassword().trim().equals("")) { addFieldError("repassword", "请输入确认密码");

}

// 校验输入的密码和确认密码是否一致

if (!getPassword().equals(getRepassword())) {

addFieldError("repassword", "确认密码和密码输入不一致");

}

if (getMobile().length() != 11) { // 校验输入的手机号码长度是否正确

addFieldError("mobile", "请输入正确的手机号码");

}

if (getAge() < 1 || getAge() > 99) { // 校验输入的年龄是否正确

addFieldError("age", "请输入您的真实年龄");

}

}

}

运行结果如图3-10所示。

图3-10 validateXXX方法校验没有输入数据

2.使用Struts2框架校验

Struts2框架提供了一种基于框架文件的输入校验方式,将校验规则保存在特定的框架

文件中,这样就使输入校验同Action实现分离,提高了系统的维护性。

Struts2使用配置文件来完成输入校验方式步骤:首先在Action 代码中去除所有validate与validateXXX 方法的代码。然后在和Action 类文件同一级目录下增加XXX-validation.xml 配置文件。这里“XXX ”是Action 类文件名字,表示该XML 文件中所有输入校验的规则定义和错误信息显示方式都只针对该Action 有效。

1.Struts2 字段校验

Struts2字段校验是在之间使用来对输入界面表单中每一个字段进行输入校验规制定义和错误定义。中的name属性就是字段名字。它包含标签,它的type 属性表明是何种类型的输入校验。这些输入校验的type 都是在Struts2 中缺省定义的,被称之为校验器。在 标签内可以有 2 种标签,一种是 标签,该标签定义了一些输入校验规则需要用到的参数。这些参数更可以以“${ 参数名} ”格式显示在视图页面上。除此之外还有 标签,该标签定义的是输入校验出错后的出错信息。这些信息是可以显示在试图界面上的。

【例3-6】使用Struts2字段校验实例。

(1)注册页面:register2.jsp

<%@ page language="java" pageEncoding="gb2312"%>

<%@taglib prefix="s" uri="/struts-tags"%>

注册页面

(2)注册控制类:RegisterAction2.java

package https://www.doczj.com/doc/a13203606.html,it;

import java.util.Date;

import com.opensymphony.xwork2.ActionSupport;

public class RegisterAction2 extends ActionSupport {

private static String FORWARD = null;

private String username; // 用户名属性

private String password; // 密码属性

private String repassword; // 确认密码属性

private Date birthday; // 生日属性

private String mobile; // 手机号码属性

private int age; // 年龄属性

public String getUsername() { // 取得用户名值

return username;

}

public void setUsername(String username) { // 设置用户名值https://www.doczj.com/doc/a13203606.html,ername = username;

}

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 Date getBirthday() { // 取得生日值

return birthday;

}

public void setBirthday(Date birthday) { // 设置生日值

this.birthday = birthday;

}

public String getMobile() { // 取得手机号码值

return mobile;

}

public void setMobile(String mobile) { // 设置手机号码值

this.mobile = mobile;

}

public int getAge() { // 取得年龄值

return age;

}

public void setAge(int age) { // 设置年龄值

this.age = age;

}

// 执行注册方法

public String Register() throws Exception {

FORWARD = "success";

return FORWARD;

}

}

(3)字段校验配置文件:RegisterAction2-validation.xml

"-//OpenSymphony Group//XWork Validator 1.0.2//EN"

"https://www.doczj.com/doc/a13203606.html,/xwork/xwork-validator-1.0.2.dtd">

6

8

用户名长度必须在${minLength}-${maxLength}位之间

请输入用户名

6

8

密码长度必须在${minLength}-${maxLength}位之间

请输入密码

6

8

确认密码长度必须在${minLength}-${maxLength}位之间

请输入确认密码

password==repassword

确认密码和密码输入不一致

请输入生日日期

1928-01-01

2004-01-01

输入生日日期无效

请输入手机号码

11

请输入正确的手机号码,号码位数必须为11位

请输入年龄

1

80

年龄必须在${min}-${max}岁之间

运行结果与例3-5相似。

2. Struts2 非字段校验

非字段格式的输入校验方式与上字段校验相比主要是它的书写格式不是像之前在 之间包含标签,而是标签。每个 标签定义的type 属性还是Struts2 自带的输入校验器的类型格式。

标签之内包含的还是两种标签。但是在中多定义了一个fieldName 属性。这个属性定义的就是输入校验的表单字段名字。其他和之前字段格式都类似。

【例3-7】使用Struts2非字段校验实例。

⑴注册页面与注册控制类与例3-5一致。

⑵非字段校验配置文件:RegisterAction3-validation.xml

"-//OpenSymphony Group//XWork Validator 1.0.2//EN"

"https://www.doczj.com/doc/a13203606.html,/xwork/xwork-validator-1.0.2.dtd">

username

6

8

用户名长度必须在${minLength}-${maxLength}位之间

username

请输入用户名

password

6

8

密码长度必须在${minLength}-${maxLength}位之间

password

请输入密码

repassword

6

8

确认密码长度必须在${minLength}-${maxLength}位之间

repassword

请输入确认密码

password

repassword

password==repassword

确认密码和密码输入不一致

birthday

请输入生日日期

birthday

1928-01-01

2004-01-01

输入生日日期无效

mobile

请输入手机号码

mobile

请输入正确的手机号码,号码位数必须为11位

age

请输入年龄

age

1

80

年龄必须在${min}-${max}岁之间

三、拦截器

1.1.1拦截器简介

拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。拦截是AOP的一种实现策略。

拦截器(Interceptor)是动态拦截Action调用的对象,类似于Servlet中的过滤器。在执行Action的业务逻辑处理方法(execute())之前,Struts2会首先执行在struts.xml中引用的拦截器。拦截器是struts2的一个重要特性。Struts2框架的大多数核心功能都是通过拦截器来实现的,如避免表单重复提交、类型转换、对象组装、验证、文件上传等,都是在拦截器的帮助下实现的。

拦截器之所以称为“拦截器”,是因为它可以在Action执行之前和执行之后拦截调用。Struts2将它的核心功能放到拦截器中实现,而不是分散到Action中实现,有利于系统的解耦,使得功能的实现类似于个人电脑的组装,变成了可插拔的,需要某个功能就“插入”一个拦截器,不需要某个功能就“拔出”一个拦截器。你可以任意组合拦截器来为Action提供附加的功能,而不需要修改Action的代码。拦截器围绕着Action和Result的执行,其工作方式如图3-1所示。

图3-1 Struts2拦截器工作方式

从图中可以看到,在Action和Result执行之前,为Action配置的拦截器将首先被执行,在Action和Result执行之后,拦截器将重新获得控制权,然后按照与先前调用相反的顺序依次执行。在整个执行过程中,任何一个拦截器都可以选择直接返回,从而终止余下的拦截器、Action和Result的执行。例如:当一个未授权的用户访问受保护的资源时,执行身份验证的拦截器可以直接返回。

1.1.2Struts2拦截器

Struts2内置了大量的拦截器,这些拦截器以name-class对的形式配置在struts-default.xml 文件中,其中name是拦截器的名字,就是以后使用该拦截器的唯一标识;class则指定了该拦截器的实现类,如果定义的package继承了Struts2的struts-default包,则可以自由使用下面定义的拦截器,否则必须自己定义这些拦截器。

表3-1 Struts2内置拦截器

大部分时候,开发者无需手动控制这些拦截器,因为struts-default.xml文件中已经配置了这些拦截器,只要我们定义的包继承了系统的struts-default包,就可以直接使用这些拦截器。

1.定义拦截器

Struts2 拦截器定义格式为:

参数A初始化值

参数B初始化值

……

2.拦截器栈

拦截器栈:就是由多个拦截器组成的一个拦截器组,来实现一个特定的拦截功能。例如,可以可以将用户安全认证拦截器、日志拦截器、密码加密组成一个拦截器栈,在一个业务控制Action执行之前使用,比如用户注册Action,在执行该Action前来执行该拦截器栈,进行一系列公共功能方面的处理。

拦截器栈的定义:

在拦截器栈定义的元素中,name除了可以是一个拦截器名称,同时也可以是一个其它拦截器栈的名称,即该拦截器栈包含了其它拦截器栈,同时包含了该拦截器栈中所有的拦截器定义。

3.编写拦截器类

在struts2中要编写拦截器类,必须实现com.opensymphony.xwork2.interceptor.Interceptor 接口,该接口定义了如下的三个方法:

●void init():该方法在拦截器实例创建后、intercept()方法被调用之前调用,用于初始

化拦截器所需要的资源,例如数据库连接的初始化。该方法只执行一次。

●void destroy():该方法在拦截器实例被销毁之前调用,用于释放在init()方法中分配

的资源。该方法只执行一次。

●String intercept(ActionInvocation invocation) throws Exception:该方法在Action执行

之前被调用,拦截器为Action提供的附加功能在该方法中实现。利用invocation参

数,可以获取action执行的状态。在intercept()方法中,如果要继续执行后续的部分(包

括余下的应用于Action的拦截器、Action和Result),可以调用invocation.invoke()。

如果要终止后续的执行,可以直接返回一个结果码,框架将根据这个结果码来呈现

对应的结果视图。

【例3-1】HelloWorld拦截器实例。

⑴建立一个业务控制器Reg

Reg.java

package https://www.doczj.com/doc/a13203606.html,it;

import com.opensymphony.xwork2.ActionSupport;

import java.util.Date;

public class Reg extends ActionSupport{

private String username; //用户名

private String password1; //密码

private String password2; //确认密码

private Date birthday; //生日

public Date getBirthday() {

相关主题
文本预览
相关文档 最新文档