Struts中的Internationalization

关于Struts中的国际化处理,代码最能说明问题,请看。。

首先是web.xml文件

<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <init-param> <param-name>debug</param-name> <param-value>3</param-value> </init-param> <init-param> <param-name>detail</param-name> <param-value>3</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>

然后是用于选择国际化显示语言的index.jsp页面

<%@ page pageEncoding="UTF-8"%> <h2>请点击选择所要验证的语种,然后再点击登录</h2> <a href="changeLang.do?lang=zh">中文</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="changeLang.do?lang=en">英文</a> <br/> <br/> <input type="button" value="登录【Struts国际化】" οnclick="javascript:window.location='login.jsp';" />

然后是国际化显示的登录页面login.jsp

<%@ page language="java" pageEncoding="UTF-8"%> <%@ taglib prefix="bean" uri="http://struts.apache.org/tags-bean"%> <%@ taglib prefix="html" uri="http://struts.apache.org/tags-html"%> <%-- 不要忘记将默认的struts-bean.tld和struts-html.tld放置到WEB-INF目录下 --%> <h2><bean:message key="user.jsp.title"/></h2> <html:errors/> <hr/> <h4> <font color="red">提示:</font>程序设定的用户名和密码分别为 <font color="blue"><strong>admin</strong></font>和 <font color="blue"><strong>jadyer</strong></font> </h4> <form action="login.do" method="POST"> <bean:message key="user.jsp.username"/>:<input type="text" name="username"><br> <bean:message key="user.jsp.password"/>:<input type="password" name="password"><br> <input type="submit" value="<bean:message key="user.jsp.button.login"/>"> </form> <input type="button" value="<bean:message key="user.jsp.index.page"/>" οnclick="javascript:window.location='<%=request.getContextPath()%>/index.jsp';"/> <%-- ==================================================================================================== 国际化消息分为静态的和动态的 所谓静态的消息。就是硬编码,即写在页面中的,固定的字符串 还有动态的消息。动态的消息又分为提示性消息和异常消息两种 ==================================================================================================== 硬编码的国际化消息可以通过<bean:message>标签来输出 我们可以直接使用<bean:message key=""/>调用资源文件中的key来输出它的value值 它会根据浏览器的语种内核而显示相应的国际化信息 而Struts交互消息则可以通过ActionMessages等对象及相应的<html:messages/>和<html:errors/>来输出 ==================================================================================================== 因为对于不同的消息,可能会以不同的样式显示出来 比如说严重性的错误消息用红色来显示,普通的消息用蓝色显示 所以,才把动态的国际化消息又细分为两种类型 <font color="red"> <html:messages id="msg" property="error11"> <bean:write name="msg"/> </html:messages> </font> 设置输出时,严重的错误用红色显示,一般的错误用蓝色显示 <font color="blue"> <html:messages id="msg" property="error22"> <bean:write name="msg"/> </html:messages> </font> ==================================================================================================== 【<html:messages/>标签的重要属性】 id:必须属性。因为我们传递的是ActionMessages对象,而不是ActionMessage对象 ActionMessages对象相当于一个集合,我们需要在JSP上依次输出它所包含的消息 因此需要一个id标识一个变量来临时存放其每条消息 这个id属性与<logic:iterate/>标签的id属性的意义是一样的 name:指明消息对象的名称 若通过调用saveMessages或saveErrors方法来传递消息,那么这个名字不需要标识 Struts使用缺省的名称,即Globals.MESSAGE_KEY或Globals.ERROR_KEY message:由于<html:messages>标签默认是用来读取ERROR_KEY消息的 所以为了让它读取MESSAGE_KEY消息,就要为它指定message为true的属性 property:传递的ActionMessages ==================================================================================================== 【<html:messages/>和<html:errors/>的区别】 <html:messages/>既可以读ERROR_KEY消息,也可以读MESSAGE_KEY消息 <html:errors/>标签只能读ERROR_KEY消息,它与<html:messages/>类似,但无id属性 <html:errors/>可以通过header/footer以及prefix/suffix属性定制每条消息的显示格式 header/footer:定义整个错误信息显示之前【之后】所要显示的内容 这些内容也是在资源属性文件中定义的一些key值 默认的情况下,它们的取值分别为errors.header和errors.footer prefix/suffix:定义每条错误信息显示之前【之后】所要显示的内容 这些内容也是在资源属性文件中定义的一些key值 默认的情况下,它们的取值分别为errors.prefix和errors.suffix ==================================================================================================== 【国际化资源属性文件中定义的<html:errors/>标签的四个属性】 这四个Key的名字是系统定义的,不能随意更改 errors.header = <UL> errors.footer = </UL> errors.prefix = <LI><font color="red"> errors.suffix = </font></LI> ==================================================================================================== 【下面的例子取自浪曦网】 <!-- 判断:只有当lan不为空的时候才执行里面的设置时区的语句 --> <c:if test="${not empty param.lan}"> <c:if test="${param.lan=='zh'}"> <fmt:setLocale value="zh_CN"/><!-- 设置时区 --> </c:if> <c:if test="${param.lan=='en'}"> <fmt:setLocale value="en_US"/> </c:if> </c:if> <fmt:setBundle basename="com.jadyer.struts.ApplicationResources"/> <fmt:message key="lab22"/> <!-- 表单的action为空表示将请求交给自身处理 --> <form action="" method="GET" name="f1" id="f1"> <input type="radio" name="lan" value="zh" οnclick="javaScript:f1.submit()">中文 <input type="radio" name="lan" value="en" οnclick="javaScript:f1.submit()">英文 </form> 若未设置<fmt:setLocale>的scope属性,则默认的<fmt:setLocale>的作用域仅限于当前页面 设置完时区之后,再绑定资源文件。否则会按默认的浏览器的版本去访问资源文件 使用<fmt:setBundel>绑定资源文件,供<fmt:message>在特定作用域内使用 使用<fmt:setBundle>指定资源文件时仍然需要指定具体路径 最后使用<fmt:message key=""/>显示资源文件中key对应的value值 ==================================================================================================== --%>

接着是登录成功后的国际化显示的loginSuccess.jsp页面

<%@ page language="java" pageEncoding="UTF-8"%> <%@ taglib prefix="bean" uri="http://struts.apache.org/tags-bean"%> <%@ taglib prefix="html" uri="http://struts.apache.org/tags-html"%> <h2><bean:message key="user.login.success.title"/></h2> <html:messages id="msg" message="true" property="loginSuccess11"> <bean:write name="msg"/> </html:messages> <br><br> <input type="button" value="<bean:message key="user.jsp.index.page"/>" οnclick="javascript:window.location='<%=request.getContextPath()%>/index.jsp';"/>

这是Struts1.x的核心配置文件struts-config.xml

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd"> <struts-config> <form-beans> <form-bean name="loginForm" type="com.jadyer.struts.form.LoginActionForm" /> </form-beans> <action-mappings> <action path="/login" type="com.jadyer.struts.action.LoginAction" name="loginForm" scope="request" validate="false"> <forward name="success" path="/loginSuccess.jsp" /> <forward name="error" path="/login.jsp" /> </action> <action path="/changeLang" type="com.jadyer.struts.action.ChangeLanguageAction"> <forward name="index" path="/index.jsp" /> </action> </action-mappings> <message-resources parameter="res.MessageResources" /> <!-- 指定国际化时所使用的文件的baseName为MessageResources --> <!-- 若该文件存在于某个目录下,也需要指定具体的路径 --> <!-- 这里res目录不能与src目录同级,而应放到src的根目录中 --> <!-- 否则程序将识别不出该资源文件 --> </struts-config>

自定义的密码输入错误时的异常类PasswordErrorException.java

package com.jadyer.struts; @SuppressWarnings("serial") public class PasswordErrorException extends RuntimeException {}

自定义的用户名不存在时的异常类UserNotFoundException.java

package com.jadyer.struts; @SuppressWarnings("serial") public class UserNotFoundException extends RuntimeException {}

接着是用来验证用户名和密码正确与否的UserManager.java

package com.jadyer.struts; public class UserManager { private static UserManager instance = new UserManager(); private UserManager() {} public static UserManager getInstance() { return instance; } public void login(String username, String password) { if (!"admin".equals(username)) { throw new UserNotFoundException(); } if (!"jadyer".equals(password)) { throw new PasswordErrorException(); } } }

接着是用到的Struts1.x中的ActionForm类

package com.jadyer.struts.form; import javax.servlet.http.HttpServletRequest; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMapping; @SuppressWarnings("serial") public class LoginActionForm extends ActionForm { private String username; private String password; /*--两个属性的setter和getter略--*/ @Override public void reset(ActionMapping mapping, HttpServletRequest request) { System.out.println("----------LoginActionForm.reset()-----------"); } @Override public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { System.out.println("----------LoginActionForm.validate()-----------"); return null; } }

然后是用于设定国际化显示语言的Action类

package com.jadyer.struts.action; import java.util.Locale; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; /** * @see --------------------------------------------------------------------------------------------------------- * @see session是跟用户相关的,一个用户访问对应一个session会话,而浏览器的语言格式可能是不一样的 * @see 故Struts默认将不同用户的Locale信息放到各自的session中,再根据session里的Locale加载不同的配置,最后显示出来 * @see Struts利用在session中存放一个Locale对象来达到设置当前语言的目的,并将其取名为Globals.LOCALE_KEY * @see Globals是Struts框架提供的一个对象,利用这个原理,我们就可以用编程的方式手工切换整个应用系统的语言 * @see 默认的Struts根据网页向后台提交时所包含的语言编码信息,来提供缺省的Locale对象 * @see 这就是我们为什么可以通过更改网页显示语言设置,就能显示不同的语言文字的原因 * @see --------------------------------------------------------------------------------------------------------- * @see 用户访问时,他的Locale信息就被发送过去了,但Struts并不是直接加载它的 * @see 事实上,在ActionServlet初始化时,会把国际化资源文件全部加载到内存中 * @see 当有用户访问的时候,它是到内存中寻找这个文件的。这么做就会提高效率 * @see --------------------------------------------------------------------------------------------------------- * @see 【使用HTTPLook跟踪Locale信息】 * @see 首先启动HTTPLook然后点击Capture下的Start按钮,接着IE中输入http://127.0.0.1:8088/struts_i18n/并回车 * @see 再点击HTTPLook中的File下的Clear清空左栏中多出的内容,再回到IE,点击《登录》链接,页面跳转后,再回到HTTPLook中 * @see 这时在HTTPLook的右栏会看到这样的一行文字:Accept-Language:zh-cn,这是HTTP消息头,它会被发送到Tomcat中 * @see 它是通过HTTP协议,把我们的Locale信息携带过去的,然后JSP Server容器通过获取HTTP头,而得到Locale,即zh-cn * @see --------------------------------------------------------------------------------------------------------- */ 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 currentLocale = Locale.getDefault(); if ("zh".equals(lang)) { currentLocale = new Locale("zh", "CN");//构造一个Locale }else if("en".equals(lang)) { currentLocale = new Locale("en", "US"); } //request.getSession().setAttribute(Globals.LOCALE_KEY, currentLocale); //使用Action中已经封装好的setLocale()方法将Locale放到session中 //可以通过org.apache.struts.action.Action的源码来查看setLocale()方法的具体代码 //大约在org.apache.struts.action.Action的源码的最后的位置 this.setLocale(request, currentLocale); return mapping.findForward("index"); } }

接着是用于处理用户登录细节的Action类

package com.jadyer.struts.action; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionMessage; import org.apache.struts.action.ActionMessages; import com.jadyer.struts.PasswordErrorException; import com.jadyer.struts.UserManager; import com.jadyer.struts.UserNotFoundException; import com.jadyer.struts.form.LoginActionForm; /** * 消息文本的国际化处理,共有三个步骤: * 1.创建国际化消息 * 2.传递国际化消息 * 3.显示国际化消息 */ public class LoginAction extends Action { @Override public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { LoginActionForm laf = (LoginActionForm) form; String username = laf.getUsername(); String password = laf.getPassword(); // 在New一个ActionMessage对象时,需要接收一条国际化消息文本中的Key作为参数 // 也就是说,ActionMessage对象的一个实例就对应了一条国际化消息文本 // 而ActionMessages对象是ActionMessage对象的集合 // 创建的ActionMessage对象,最后必须放在ActionMessages对象中,然后再传递 // 这是因为ActionMessage可以有多个,并且<html:messages>或<html:errors>主要就是读ActionMessages的 ActionMessages messages = new ActionMessages(); try { UserManager.getInstance().login(username, password); // 创建国际化消息文本 // 如果国际化属性文件中user.login.success的值里面需要为多个占位符指定具体的值,那么就需要使用数组 // 在匹配过程中,object[0]对应属性文件中{0}的位置,object[1]对应{1}的位置,依此类推 // ActionMessage message = new ActionMessage("user.login.success", new Object[]{username}); ActionMessage message11 = new ActionMessage("user.login.success", username); messages.add("loginSuccess11", message11); ActionMessage message22 = new ActionMessage("user.login.success", username); messages.add("loginSuccess22", message22); // 传递国际化消息文本 // 详见org.apache.struts.action.Action源码的第560行 // 实际上saveMessages()是通过request.setAttribute(Globals.MESSAGE_KEY,messages)把messages对象设置到了一个常量上 // 所以,前台通过访问这个常量,就能把这个对象拿出来。而且不需要我们自己访问它,直接使用Struts中的<html:messages>标签就行了 this.saveMessages(request, messages); return mapping.findForward("success"); } catch (UserNotFoundException unfe) { unfe.printStackTrace(); // 创建国际化消息文本 ActionMessage message = new ActionMessage("user.not.found", username); messages.add("error11", message); // 传递国际化消息文本 // 该方法的方法体代码详见Action源码的第532行 // 它使用request.setAttribute(Globals.ERROR_KEY,errors)将错误消息保存在ERROR_KEY常量中 // 调用saveErrors传递错误消息,调用saveMessages()传递普通消息 // 也就是说,将普通消息放到MESSAGE中,将错误信息放到ERROR中 // 这样更便于对错误消息进行细粒度的显示。比如不同颜色的显示等等 this.saveErrors(request, messages); } catch (PasswordErrorException pee) { pee.printStackTrace(); // 创建国际化消息文本 ActionMessage message = new ActionMessage("user.password.error"); messages.add("error22", message); // 传递国际化消息文本 this.saveErrors(request, messages); } return mapping.findForward("error"); } }

最后是用到的国际化资源文件MessageResources.properties

#Generated by ResourceBundle Editor (http://eclipse-rbe.sourceforge.net) # -- standard errors -- errors.footer = </UL> errors.header = <UL> errors.prefix = <LI><font color="red"> errors.suffix = </font></LI> user.jsp.button.login = Login user.jsp.index.page = Return Index Page user.jsp.password = password user.jsp.title = User Login user.jsp.username = username user.login.success = {0},Login Success user.login.success.title = Login Success user.not.found = User Not Found,UserName=[{0}] user.password.error = Password Error #下面是MessageResources_zh_CN.properties文件的内容 errors.footer = </UL> errors.header = <UL> errors.prefix = <LI><font color="red"> errors.suffix = </font></LI> user.jsp.button.login = /u767B/u5F55 user.jsp.index.page = /u8FD4/u56DE/u9996/u9875 user.jsp.password = /u5BC6/u7801 user.jsp.title = /u7528/u6237/u767B/u5F55 user.jsp.username = /u7528/u6237 user.login.success = {0},/u767B/u5F55/u6210/u529F user.login.success.title = /u767B/u5F55/u6210/u529F user.not.found = /u7528/u6237/u4E0D/u80FD/u627E/u5230/uFF0C/u7528/u6237/u540D/u79F0=[{0}] user.password.error = /u5BC6/u7801/u9519/u8BEF

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值