一口一口吃掉Struts(九)——国际化问题(2)

Strust如何支持国际化?

(一)页面jsp)静态信息的国际化

我们以登录这个例子来说明。

一口一口吃掉Struts(九)——国际化问题(2)

通过点击中文或英文,实现登录界面语言信息的改变

主要步骤:

1、创建国际化资源文件

*与上一篇中提到的创建方式一致

属性文件内容

MessagesBoundle_zn_CN.properties

login.form.field.username=\u7528\u6237 ----如果为GBK编码,这里是“用户名”

login.form.field.password=\u5BC6\u7801 “密码”

login.form.button.login=\u767B\u5F55 “登录”

我们看到并非为中文,而是unicode编码。

这是采用JAVA_HOME/bin/native2ascii工具转换的,不然会出现乱码

MessagesBoundle_en_US.properties

login.form.field.username=user name

login.form.field.password=password

login.form.button.login=login

2、需要在struts配置文件中指定资源属性文件的位置和名称,如<message-resources parameter="MessageResources" />

*Parameter=国际化资源文件的basename即可

3、在JSP页面中使用Struts标签库来实现显示,如<bean:message key=“key string”/>来输出文本

*需要引入相应的标签库<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>

*struts 利用在 session 中存放一个 Locale 对象来达到设置当前语言的目的
*默认的情况下, struts 根据网页向后台提交时所包含的语言编码信息来提供缺省的 Locale 对象,这就是我们为什么可以通过更改网页显示语言设置,就能显示不同的语言文字的原因。
*struts session 中存放的这个 Locale 对象,取名为: Globals.LOCALE_KEY 的值 , Globals struts 框架提供的一个对象

利用这个原理,我们可以用编程的方式来手工切换整个应用系统的语言

示例:

相关action

<action path="/changeLanguage" type="com.jialin.ChangeLanguageAction"
		scope="request">
		<forward name="login" path="/index.jsp" />
</action>
public class ChangeLanguageAction extends Action {

	@Override
	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		String lang = request.getParameter("lang");
		Locale locale = Locale.getDefault();
		
		if ("zh".equals(lang)) {
			locale = new Locale("zh", "CN"); 
		}else if ("en".equals(lang)) {
			locale = new Locale("en", "US");
		}
		
		this.setLocale(request, locale);//将语言信息设置到session中		
		return mapping.findForward("login");
	}
	
}


登录JSP

<body>
   <form action="login.do" method="post">
	<bean:message key="login.form.field.username" />
	<input type="text" name="name" />
	<br />
	<bean:message key="login.form.field.password" />
	<input type="password" name="password" />
	<input type="submit" value="<bean:message key="login.form.button.login"/>" />
   </form>

	<a href="changeLanguage.do?lang=zh">中文</a> 
	<a href="changeLanguage.do?lang=en">英文</a>
</body>

页面信息的国际化还可以给我们带来另一个好处:我们可以通过修改国际化资源文件更改页面显示的内容,今天叫登录,明天可以改为开始等等。


(二)动态消息的国际化

对于消息提示,异常信息等这些动态信息,我们如何实现国际化呢?

我们依然用上面的例子,在登录验证中加入国际化

更改MessagesBoundle_zn_CN.properties

errors.header=<UL>
errors.prefix=<font color="red"><LI>
errors.suffix=</LI></font>
errors.footer=</UL>
login.form.field.username=\u7528\u6237
login.form.field.password=\u5BC6\u7801
login.form.button.login=\u767B\u5F55
login.success={0},\u767B\u5F55\u6210\u529F --登录成功
login.user.not.found=\u7528\u6237\u4E0D\u80FD\u627E\u5230\uFF0C\u7528\u6237\u540D\u79F0\=\u3010{0}\u3011 --用户未找到,用户=
login.password.error=\u5BC6\u7801\u9519\u8BEF --密码错误

更改MessagesBoundle_en_US.properties

errors.header=<UL>
errors.prefix=<font color="red"><LI>
errors.suffix=</LI></font>
errors.footer=</UL>
login.form.field.username=user name
login.form.field.password=password
login.form.button.login=login
login.success={0},Login Success
login.user.not.found=user not found,user name=[{0}]
login.password.error=password error

Struts配置文件

<struts-config>

	<!-- set ActionForm info-->
	<form-beans>
		<form-bean name="userForm" type="com.jialin.UserActionForm" />
	</form-beans>
	
	<global-forwards>
		<forward name="login" path="/index.jsp" />
		<forward name="success" path="/LoginSuccess.jsp" />
		<forward name="fail" path="/LoginFail.jsp" />
	</global-forwards>
	
	<action-mappings>
		<!-- Set path,action,actionform,scope,forward info -->
		<action path="/login" type="com.jialin.LoginAction" name="userForm"
			scope="request" validate="true" attribute="uf">
		</action>

		<action path="/changeLanguage" type="com.jialin.ChangeLanguageAction"
			scope="request">
		</action>
	</action-mappings>

	<message-resources parameter="com.jialin.resource.MessagesBoundle"></message-resources>

</struts-config>


LoginAction

第一步:在这个LoginAction中,我们将根据业务逻辑需要获取国际化消息文本ActionMessage,然后将他保存起来到ActionMessages里

ActionMessages ActionMessage 对象
*ActionMessages对象是ActionMessage对象的集合
*一个ActionMessage对象,代表一个国际化消息文本(字符串)

第二步:保存这个ActionMessages,用于传递

首先我们要判断要传递的消息是普通消息还是错误消息?

*普通消息:即普通的消息文本

*错误消息:即异常消息文本

本质上,这两种消息没有什么区别,都是消息文本,但是如果一个页面同时需要显示普通的消息文本和错误消息文本的时候,就需要进行区分了,比如不同类型的消息文本可能要用不同的样式来显示

/**
 * 登录action
 * @author jialin
 *作用:取得表单数据,调用model层业务逻辑,返回转向信息
 */
public class LoginAction extends Action {

	@Override
	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		UserActionForm  userForm=(UserActionForm)form;
		String userName=userForm.getName();
		int password=userForm.getPassword();  //这里不用我们手动强转类型了。
		
		UserManage userManage=new UserManage();
		User user=new User();
		user.setName(userName);
		user.setPassword(password);
		ActionMessages messages = new ActionMessages();
		
		
		try {
			userManage.ValidateUser(user);
			//创建国际化消息文本
			ActionMessage message=new ActionMessage("login.success", userName);
			messages.add("login_message_1",message);
			
			//传递国际化消息,普通消息
			this.saveMessages(request, messages);
			
			return mapping.findForward("success");
		
		} catch (UserNotFoundException e) {
			//创建国际化消息文本
			ActionMessage message=new ActionMessage("login.user.not.found", userName);
			messages.add("login_error_1",message);
			
			//传递国际化消息,异常消息
			this.saveErrors(request, messages);
			
		}catch (PasswordErrorException e) {
			//创建国际化消息文本
			ActionMessage message=new ActionMessage("login.password.error", userName);
			messages.add("login_error_2",message);
			
			//传递国际化消息,异常消息
			this.saveErrors(request, messages);
		}
		
		return mapping.findForward("fail");
		
	}

}

UserManage

/**
 * MODEL层业务逻辑
 * 
 * @author jialin 判断用户是否合法
 */
public class UserManage {

	public void ValidateUser(User user) {
		// 判断用户名密码是否正确
		if (!"jialin".equals(user.getName())) {
			//"用户不存在!用户名为:" + user.getName()"会被Struts用于填充占位符
			throw new UserNotFoundException("用户不存在!用户名为:" + user.getName());
		} else if (user.getPassword() != 123456) {
			//"密码错误“会被Struts用于填充占位符
			throw new PasswordErrorException("密码错误");
		}
	}
}

自定义异常类PasswordErrorException,UserNotFoundException略

登录失败jsp

	<body>
		<font color="red"> <html:messages id="msg"
				property="login_error_1">
				<bean:write name="msg" />
			</html:messages> </font>
		<font color="blue"> <html:messages id="msg"
				property="login_error_2">
				<bean:write name="msg" />
			</html:messages> </font>
	</body>

别忘记引入taglib

<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean"%>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>

也可以用<html:errors />代替<font color="red"> <html:messages id="msg"property="login_error_1"><bean:write name="msg" /></html:messages> </font><font color="blue"> <html:messages id="msg"property="login_error_2"><bean:write name="msg" /></html:messages> </font>显示异常信息

< html:errors /> 标签只显示错误消息
< html:errors /> 标签与 < html:messages /> 标签类似,但无 id 属性
< html:errors /> 标签通过提供 header/footer 属性以及 prefix/suffix 属性来定制每条消息的显示格式
header/footer – 定义整个错误消息显示之前(之后)要显示的内容,这些内容也是在资源属性文件中定义的一些key值,默认的情况下,它们的取值分别为:errors.header和errors.footer
prefix/suffix – 定义每条错误消息显示之前(之后)要显示的内容,这些内容也是在资源属性文件中定义的一些key值,默认的情况下,它们的取值分别为:errors.prefix和errors.suffix
举例如下(见国际化资源文件):

errors.header=<UL>

errors.prefix=<LI>

errors.suffix=</LI>

errors.footer=</UL>


登录成功jsp

<body>
		<html:messages id="msg" message="true">
			<bean:write name="msg" />
		</html:messages>
	</body>



效果就贴图了,下篇接着说struts对异常的处理


你可能感兴趣的:(struts)