(1)国际化的单词 internationalization,简写做 i18n。指一个应用程序在运行时,能够根据客户端请求所来自国家或地区语言的不同,而显示不同的语言界面。
(2)前提知识:
① Locale:java中的一个类,表示地区。每一个 Locale 对象都代表了一个特定的地理、文化、语言区域。
常用的国家和语言的代号:
zh-CN:中文-中国
en-US:英文-美国
ja-JP: 日语-日本
ko-KR:韩语-韩国
每个浏览器在都有默认的语言和区域,当浏览器发送请求时,在请求头中就包含了这些信息,这些信息会一起发送到服务器。通过这些信息,服务器可以判断发送请求的客户端所使用的的语言。
② ResourceBundle:java 中的一个类,可以用键值对的方式保存一个资源文件中的信息和 Properties 类相似。
(3)Struts2 实现国际化依赖于 Struts2 的 i18n 拦截器,在该拦截器中会判断发送请求的客户端所使用的的语言,通过语言代号从对应的资源文件中读取网页上所需的文本信息(资源文件需要开发者提供),将读取到的信息一起保存到 ResourceBundle 类中,最后在页面上使用 struts2 提供的标签库将 ResourceBundle 对象中的数据展示到网页上。
(1)开发人员需要根据自己的需求(需要国际化的语言种类),为每一个 Locale 提供一个资源文件,该资源文件中定义了网页中出现的各种文本信息。为了便于 Struts2 的查找,需要提供一个统一的资源文件前缀名称。
(2)假如我们要为中文-中国以及英语-美国这两个地区的用户提供国际化,那么我们需要在src目录下提供两个资源文件,两个资源文件的命名规则是统一的前缀_语种_国家.properties
,两个资源文件中采用相同的键来保存数据,但是一个资源文件中用中文定义值,另外一个用英文定义值。如下:
message_zh_CN.properties:
username=用户名
password=密码
submit=提交
login=登录
message_en_US.properties
username=username
password=password
submit=submit
login=login
(3)Struts2 加载资源文件是在 i18n 拦截器中完成的,那么我们访问 jsp 网页时,也必须要执行 i18n 拦截器才行,所以我们必须使用 Action 来响应一个 jsp 的方式,让 jsp 的网页请求也能经过拦截器。上面章节讲到过使用统一的 Aciton 来响应 jsp 请求的方式,这里也可以这样做。
/WEB-INF/page/{1}.jsp
(4)最后,在网页中使用 Struts2 的标签库来加载国际化之后的网页文本信息。
<%@ taglib prefix="s" uri="/struts-tags" %>
上述方式完成国际化必须要借用Struts2标签库,但是Struts2标签库在企业中很少使用,那么能否不使用Struts2标签库也能完成国际化呢?
国际化的核心就是根据请求中的语种和区域加载不同的资源文件,然后将资源文件中的信息动态的显示到网页中,那么我们能否将资源文件中的信息存放到request作用域,然后使用EL表达式的方式来展示国际化数据呢。
(1)定义一个 jsp 网页,通过表单提交数据到 Action 中,服务端的数据校验在一个 web 项目中是必不可少的部分,Struts2 提供了多种方式可以进行数据校验。
(1)首先在 Action 中定义适当的对象接收客户端传递的参数
(2)在 Action 中重写 validate 方法,在该方法中对于对象中接收的数据进行判断,如果不合法则执行 this.addFieldError(“键”,”值”) 方法,该方法有两个作用第一个作用是将错误信息保存在 request 作用域中的 fieldErrors 属性中,换句话说 fieldErrors 是所有的错误信息,通过 fieldErrors.键 可以从作用域中取出其中一个错误信息,第二个作用是返回 input 逻辑视图。
@Override
public void validate(){
if(userEntity.getUserName().equals("")){
this.addFieldError("userName", "用户名不能为空");
}
if(userEntity.getPassWord().equals("")){
this.addFieldError("passWord", "密码名不能为空");
}
}
(3)在action标签中对input逻辑视图进行映射
success.jsp
login.jsp
(4)在表单所在的网页中使用el表达式,从request作用域中取出错误信息,显示在网页上。
${fielderrors.userName}
重写validate方法确实可以完成数据校验的工作,但是如果在一个Action中定义了多个方法,那就会出现问题,因为每一个方法都是用来处理不同的请求的,请求不同所需要的参数自然也不一样,通过一个方法来验证数据,难免会出现顾此失彼的情况。
在Action中可以定义多个方法,方法的命名规则是
[validate+需要验证的方法名首字母大写]
例如要验证登录方法,需要定义一个方法 validateLogin(),要验证注册方法需要定义一个方法 validateRegister()。其他的验证过程完全一致。
除了上述两种方式外,Struts2 还提供了基于 validation 验证框架的参数校验方式,该方式的优点是对于参数的校验利于复用,不用编码,更利于维护。
validation 验证框架工作流程是通过在配置文件中定义验证规则,然后让Struts2自动完成校验。
(1)准备好表单和处理请求的 Action 类和 struts.xml 配置文件
① 表单请求(注册)
② struts.xml 配置文件
main.jsp
regist.jsp
③ 实体类
public class UserFormCheckAction extends ActionSupport{
//两次密码输入
private String passWord1;
private String passWord2;
//实体类对象
private UserEntity userEntity;
//省略set、get方法
//注册验证
public String login() {
return Action.SUCCESS;
}
}
(2)在 Action 类同目录下定义一个[Action类名-validation.xml]
文件,该文件需要引入 validation 的 dtd 文件。
(3)在该 xml 文件中对于传递到服务器的参数制定校验规则,校验规则有如下几种:
属性验证语法:
错误信息
配置该 xml 文件如下(UserFormCheckAction-regist-validation.xml
):
用户名不能为空
6
10
用户名长度为6-10位
密码不能为空
6
16
密码长度为6-16位
密码不能为空
6
16
密码长度不合法
(passWord1 eq passWord2)
两次输入密码不一致
邮箱不能为空
邮箱格式不合法
手机号码不能为空
手机号码格式不正确
(4)在表单页面使用s标签库显示错误信息
userEntity.userName
(5)常用的验证示例
① 必填检验
指定检验失败的提示信息
② 必填字符串检验
true
指定检验失败的提示信息
③ 整数检验器/浮点检验
1
150
年纪必须在1到150之间
④ 日期检验
1900-01-01
2050-02-21
⑤ 字段表达式检验器(要求指定字段满足一个逻辑表达式)
(pass eq re_pass)
密码必须和确认密码相等
⑥ 邮件地址校验
你的电子邮件地址必须是一个有效的电邮地址
⑦ 网址检验
你的主页地址必须是一个有效的网址
⑧ 字符串长度检验
6
16
你的用户名长度必须在4到20之间
⑨ 正则表达式检验
您输入的用户名只能是字母和数组,且长度必须在4到25之间
上述验证方式是面向Action类的,会对所有请求到Action类中的方法进行验证,同样会有顾此失彼的问题,我们可以为每一个action请求定义对应的验证规则,同样是通过xml文件来实现的,但是该xml文件的命名方式为[Action类-请求地址-validation.xml],其余配置方式完全一致。