所謂的i18n問題指的是(軟件的)國際化問題,簡單來說就是使咱們的軟件可讓世界使用任何語言的人們都能使用,軟件自身會根據語言環境的不一樣進行自動配置,若是你是中文環境那界面以中文顯示,若是是英文環境就以英文顯示。在i18n問題的解決中,國際化資源文件是不可或缺的,程序正是經過對資源文件的讀取來決定究竟以何種界面顯示。說到這裏若是你認爲國際化資源文件僅僅可以解決不一樣語言版本的顯示問題那你就錯了,經過對國際化資源文件進行配置咱們一樣能夠實現消息的動態建立和顯示。下面咱們就來經過實例詳細講解struts如何解決i18n問題。html
首先來簡單瞭解國際化資源文件。國際化資源文件是由basename + local+.properties構成的,local指的是語言環境,缺省的local是由操做系統決定的,local由語言和國家代碼組成,basename爲MessagesBundle,以中文爲例,其資源文件名稱爲:MessagesBundle_zh_CN.properties,缺省的國際化資源文件名稱爲MessagesBundle.properties。在該文件中,存儲方式爲key-value形式,全部的key均對應一個value值,程序經過讀取該文件中的key值肯定應顯示的文本。下面經過實例來說解用struts如何應用資源文件解決i18n問題。java
1. struts的國際化配置。在struts-config.xml文件中加入<message-resourcesparameter="MessageResources"/>。注意parameter的值爲國際化資源文件所在的路徑,若是國際化資源文件位於src下一個名爲resources的文件夾下,則此處parameter的值應爲「resources.MessageResources」。node
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd"> <struts-config> <form-beans> <form-bean name="loginForm" type="com.bjpowernode.struts.LoginActionForm"/> </form-beans> <action-mappings> <action path="/login" type="com.bjpowernode.struts.LoginAction" name="loginForm" scope="request" > <forward name="success" path="/login_success.jsp"/> <forward name="error" path="/login.jsp"/> </action> <action path="/changLang" type="com.bjpowernode.struts.ChangeLanguageAction" > <forward name="index" path="/index.jsp"></forward> </action> </action-mappings> <message-resources parameter="resources.MessageResources"/> </struts-config>
2. 提供國際化資源文件。在本例中咱們提供三個國際化資源文件,分別爲:中文的國際化資源文件MessageResources_zh_CN.properties,英文的國際化資源文件MessageResources_en_US.properties以及缺省的國際化資源文件:MessageResources.properties。注意在中文的國際化文件中,須要把全部的中文轉換成unicode編碼格式。apache
3.利用struts默認將locale放到session中的特性,咱們能夠完成語言的自動切換。session
package com.bjpowernode.struts; import java.util.Locale; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.Globals; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; public class ChangeLanguageAction extends Action { @Override public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { //取得客戶端傳過來的參數 String lang = request.getParameter("lang"); //取得session中默認的locale Locale locale = Locale.getDefault(); //若是傳過來的參數爲「zh」將locale設爲中文,若是參數爲「en」則將locale設爲英文 if("zh".equals(lang)){ locale = new Locale("zh","CN"); }else if("en".equals(lang)){ locale = new Locale("en", "US"); } //將locale設置到session中 //request.getSession().setAttribute(Globals.LOCALE_KEY, locale); this.setLocale(request, locale); return mapping.findForward("index"); } }
4.上文中咱們已經提過國際化資源文件的做用並不單單在於語言環境的轉變,他還支持頁面的個性化設計以及動態消息的建立。下面咱們提供一個英文的資源文件,並以此文件爲例介紹動態消息的建立。
app
4.1 英文國際化資源文件:jsp
errors.header=<UL> errors.prefix=<font color="blue"><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,UserName\=[{0}] login.password.error=Password Error
4.2 建立動態消息。動態消息的建立分爲三個步驟,分別是 建立國際化消息文本,傳遞國際化消息文本,顯示國際化消息文本。在上面的資源文件按中咱們能夠看到佔位符的存在,佔位符的存在就給咱們動態的建立信息提供了可能,下面看咱們是如何經過填充佔位符建立動態信息的。 ide
package com.bjpowernode.struts; 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; 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(); UserManager userManager = new UserManager(); ActionMessages messages = new ActionMessages(); try{ userManager.login(username, password); //建立國際化消息文本 //ActionMessage message = new ActionMessage("login.success",new Object[]{username}); ActionMessage message = new ActionMessage("login.success",username); messages.add("login_success_1",message); ActionMessage message1 = new ActionMessage("login.success",username); messages.add("login_success_2",message1); //傳遞國際化消息 this.saveMessages(request, messages); return mapping.findForward("success"); }catch(UserNotFoundException e){ e.printStackTrace(); //建立國際化消息文本 ActionMessage error = new ActionMessage("login.user.not.found",username); messages.add("error_1",error); //傳遞國際化消息 this.saveErrors(request, messages); }catch(PasswordErrorException e){ e.printStackTrace(); //建立國際化消息文本 ActionMessage error = new ActionMessage("login.password.error"); messages.add("error_2",error); //傳遞國際化消息 this.saveErrors(request, messages); } return mapping.findForward("error"); } }
請注意上面代碼中的這條語句:ActionMessagemessage = new ActionMessage("login.success",username);,該語句的做用就在於填充國際化資源文件中的佔位符,經過這種方式咱們能夠動態的建立消息。ui
5. 在jsp中採用<bean:message>讀取國際化消息文本(本例中以登陸成功後的頁面爲例)。this
<%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GB18030"%> <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=GB18030"> <title>Insert title here</title> </head> <body> <html:messages id="msg" message="true" > <bean:write name="msg"/> </html:messages> </body> </html>
在該jsp中咱們採用的是html:messages標籤來讀取信息的,在這裏須要注意的一點是,這個標籤既能夠讀取message key又能夠讀取error key,而html:error標籤只能夠讀取error key。根據這一點咱們能夠決定在錯誤處理頁面和成功頁面具體使用哪一種標籤進行讀取。另外使用jstl標籤一樣能夠讀取國際化資源文件中的消息,再引入jstl格式化標籤庫後,使用<html:errors>標籤能夠讀取錯誤信息,使用<fmt:message>標籤能夠讀取消息。