displaytag 国际化 探索日志 注释
使用displaytag中的titleKey無效?????????????不顯示???????無法國際化???????
如何使用國際化??????
?
?
我先是嘗試了網上的方法,修改屬性文件中的locale.provider、locale.resolver的值為新建的I18nStruts2Adapter。。。
屢屢嘗試不得結果。。。決心使用系統默認的jstl國際化方案。。。
首先,在源碼中可以看到:
/*
?* To change this template, choose Tools | Templates
?* and open the template in the editor.
?*/
package testList;
/**
?* Licensed under the Artistic License; you may not use this file
?* except in compliance with the License.
?* You may obtain a copy of the License at
?*
?*??????http://displaytag.sourceforge.net/license.html
?*
?* THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
?* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
?* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
?*/
//package org.displaytag.localization;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.jstl.core.Config;
import javax.servlet.jsp.jstl.fmt.LocalizationContext;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.taglibs.standard.tag.common.fmt.BundleSupport;
import org.displaytag.Messages;
import org.displaytag.localization.I18nResourceProvider;
import org.displaytag.localization.LocaleResolver;
/**
?* JSTL implementation of a resource provider and locale resolver. It will make the <code>titleKey</code>
attribute of
?* column tag works the same as fmt:message's <code>key property</code>. This tag must be the descendant of a
?* <code>fmt:bundle</code> tag in order to use the titleKey. This is just a shortcut, which makes
?*
?* <pre>
?* <display:column titleKey="bar"/>
?* </pre>
?*
?* behave the same as
?*
?* <pre>
?* <c:set var="foo">
?*?? <fmt:message key="bar"/>
?* </c:set>
?* <display:column title="${foo}"/>
?* </pre>
?*
?* If you don't define either <code>titleKey</code> or <code>titleKey</code> property on your column, first the
tag
?* will attempt to look up the <code>property</code> property in your ResourceBundle. Failing that, it will fall
back
?* to the parent class's behavior of just using the property name.
?* @author Fabrizio Giustina
?* @version $Revision: 1081 $ ($Author: fgiust $)
?*/
public class I18nJstlAdapter implements I18nResourceProvider, LocaleResolver
{
??? /**
???? * prefix/suffix for missing entries.
???? */
??? public static final String UNDEFINED_KEY = "???"; //$NON-NLS-1$
??? /**
???? * logger.
???? */
??? private static Log log = LogFactory.getLog(I18nJstlAdapter.class);
??? /**
???? * Instantiates a new I18nJstlAdapter. Throw a NoClassDefFound error if BundleSupport is not available.
???? */
??? public I18nJstlAdapter()
??? {
??????? // this will check if BundleSupport is available
??????? // if a NoClassDefFound error is thrown, the I18nJstlAdapter will not be used
??????? BundleSupport.class.hashCode();
??? }
??? /**
???? * @see LocaleResolver#resolveLocale(HttpServletRequest)
???? */
??? public Locale resolveLocale(HttpServletRequest request)
??? {
??????? //System.out.println("....sdsa.f.af.as.fas.fa.....................");
??????? Locale locale = (Locale) Config.get(request.getSession(), Config.FMT_LOCALE);
??????? if (locale == null)
??????? {
??????????? locale = request.getLocale();
??????? }
??????? return locale;
??? }
??? /**
???? * @see I18nResourceProvider#getResource(String, String, Tag, PageContext)
???? */
??? public String getResource(String resourceKey, String defaultValue, Tag tag, PageContext pageContext)
??? {
??????? // if titleKey isn't defined either, use property
?????? // System.out.println("resourceKey.....................:"+resourceKey);
????? //? System.out.println("defaultValue.....................:"+defaultValue);
??????? String key = (resourceKey != null) ? resourceKey : defaultValue;
??????? String title = null;
??????? ResourceBundle bundle = null;
??????? // jakarta jstl implementation, there is no other way to get the bundle from the parent fmt:bundle tag
??????? Tag bundleTag = TagSupport.findAncestorWithClass(tag, BundleSupport.class);
??????? if (bundleTag != null)
??????? {
??????????? BundleSupport parent = (BundleSupport) bundleTag;
??????????? if (key != null)
??????????? {
??????????????? String prefix = parent.getPrefix();
??????????????? if (prefix != null)
??????????????? {
??????????????????? key = prefix + key;
??????????????? }
??????????? }
??????????? bundle = parent.getLocalizationContext().getResourceBundle();
??????? }
??????? // resin jstl implementation, more versatile (we don't need to look up resin classes)
??????? if (bundle == null)
??????? {
??????????? Object cauchoBundle = pageContext.getAttribute("caucho.bundle"); //$NON-NLS-1$
??????????? if (cauchoBundle != null && cauchoBundle instanceof LocalizationContext)
??????????? {
??????????????? bundle = ((LocalizationContext) cauchoBundle).getResourceBundle();
??????????????? // handle prefix just like resin does
??????????????? String prefix = (String) pageContext.getAttribute("caucho.bundle.prefix"); //$NON-NLS-1$
??????????????? if (prefix != null)
??????????????? {
??????????????????? key = prefix + key;
??????????????? }
??????????? }
??????? }
??????? // standard jstl localizationContest
??????? if (bundle == null)
??????? {
??????????? // check for the localizationContext in applicationScope, set in web.xml
??????????? LocalizationContext localization = BundleSupport.getLocalizationContext(pageContext);
??????????? if (localization != null)
??????????? {
??????????????? bundle = localization.getResourceBundle();
??????????? }
??????? }
??????? if (bundle != null)
??????? {
??????????? try
??????????? {
??????????????? title = bundle.getString(key);
??????????? }
??????????? catch (MissingResourceException e)
??????????? {
??????????????? log.debug(Messages.getString("Localization.missingkey", key)); //$NON-NLS-1$
??????????????? // if user explicitely added a titleKey we guess this is an error
??????????????? if (resourceKey != null)
??????????????? {
??????????????????? title = UNDEFINED_KEY + resourceKey + UNDEFINED_KEY;
??????????????? }
??????????? }
??????? }
??????? return title;
??? }
}
留意當中提到的,<display:column titleKey="bar"/>等效于<c:set var="foo"><fmt:message key="bar"/></c:set>
?<display:column title="${foo}"/>
接著,我們需要確定一點,使用c:set、fmt:message 需要什么?
顯然,在頁面中需要導入包:
<%@ taglib uri="http://displaytag.sf.net/el" prefix="display" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
< uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
?
再者,我們根據上面的注釋,可以得到:
有title則不會看titleKey,看titleKey時會去看你的resourceBundle。。。resourceBundle取決于你在displaytag.properties
中的對locale.provider的設定,當然,如果不設定,默認值locale.provider=org.displaytag.localization.I18nJstlAdapter
,而locale.resolver默認值為空。當然,你可以自定義國際化的方式,比如使用struts1.x,webwork等。但是struts2好像不支
持,網上有些參考代碼,我前面試了,但是好像不能解決這個問題。
若以上國際化方式均失敗了,則會去看property。。。。。。即數據庫中的列名。。。。
?
再看看我自己的jsp代碼:
<%--?
??? Document?? : newjsp
??? Created on : 2011-3-5, 21:35:39
??? Author???? : xtz
--%>
< contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
?? "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib uri="http://displaytag.sf.net/el" prefix="display" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
< uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<? import="java.util.*,testList.Test" %>
<html>
??? <head>
??????? <link rel="stylesheet" type="text/css" href="css/screen.css" />
??????? <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
??????? <title>displaytag</title>
??? </head>
??? <body>
??????? <h1>Hello Displaytag!</h1>
??????? <%
??????? List pageList = new ArrayList();
??????? for(int i=0;i<40;i++)
?????? pageList.add(i, new Test("123","1","1"));
?????? request.setAttribute("pageList", pageList);
??????? %>
?????? <s:form >
?????????? <s:textfield key="test"? />
?????? </s:form>
?????? <fmt:setLocale value="en_US"/><%--格式:en_US zh_CN--%>
?????? <fmt:bundle basename="testList.titleKeyResource"><!--資源文件的名字,注意要放在CLASSES下面-->
?????????? <fmt:message key="test" />
???????????
?????????? <display:table name="pageList"? id="row" class="table" pagesize="20" export="true">
??????????? <%--注意上面:需要完整路徑!--%>
??????????? <%-- title="struts2Id" title="struts2Name" 似乎是直接用來顯示的,titleKey才是國際化關鍵key~~~
?????????? value="struts2IdValue" 不知道有什么用 --%>
??????????? <c:set var="foo">
??????????????? <fmt:message key="test"/>
??????????? </c:set>
??????????? <display:column? property="id"?? title="${foo}"? />
??????????? <display:column property="name"? titleKey="test" value="aa" title="${test}" />
??????????? <display:column property="address" title="new address"/>
???????????? <c:set var="foo">
??????????????? <fmt:message key="struts2IdKey"/>
??????????? </c:set>
??????????? <display:column property="remark" title="${foo}"/>
??????????? <display:setProperty name="export.rtf.filename" value="example.rtf"/>
??????????? <display:setProperty name="export.pdf" value="false" />
??????? </display:table>
??????? </fmt:bundle>
??? </body>
</html>
不知道為什么,jstl本身的國際化可以顯示,而display標簽中的就是不顯示?????????不工作?????
?
仔細檢查代碼,首先我用的是系統默認的國際化方式,即jstl。。。。所以displaytag屬性文件基本上不用改。。。。
而我對jstl的使用格式是正確的。。。相關包也導入了。。。我甚至把I18nJstlAdapter拉了出來測試。。。。
當然都無果而終。。。。囧。。。。。
情急之下,甚至上google 英文進行搜索,搜英文的。。。很多網頁開不了。。。。。
悲憤之中。。。看見網上有些達人寫的原創博文較多,而且能解決很多問題。。。
其中某某還在博文內附上了聯系郵箱。。。一種發郵件請教的沖動油然而生。。。。。。。
郵件寫好了,想著最好附上代碼,發覺代碼很亂,決定整理一下,弄個簡化的發過去。。。。
整理ing。。。。。。。
簡化:
< contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
?? "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib uri="http://displaytag.sf.net/el" prefix="display" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
< uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<? import="java.util.*,testList.Test" %>
<html>
??? <head>
??????? <link rel="stylesheet" type="text/css" href="css/screen.css" />
??????? <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
??????? <title>displaytag</title>
??? </head>
??? <body>
??????? <h1>Hello Displaytag!</h1>
??????? <%
??????? List pageList = new ArrayList();
??????? for(int i=0;i<40;i++)
?????? pageList.add(i, new Test("123","1","1"));
?????? request.setAttribute("pageList", pageList);
??????? %>
?????? <s:form >
?????????? <s:textfield key="test"? />
?????? </s:form>
?????? <fmt:setLocale value="zh_CN"/><%--格式:en_US zh_CN--%>
?????? <fmt:bundle basename="testList.titleKeyResource"><!--資源文件的名字,注意要放在CLASSES下面-->
?????????? <fmt:message key="test" />
???????????
?????????? <display:table name="pageList"? id="row" class="table" pagesize="20" export="true">
??????????? <%--注意上面:需要完整路徑!--%>
??????????? <%-- title="struts2Id" title="struts2Name" 似乎是直接用來顯示的,會覆蓋屬性文件中titleKey對應的值,
titleKey才是國際化關鍵key~~~
?????????? value="struts2IdValue" 不知道有什么用 --%>
??????????? <display:column? property="id"?? titleKey="struts2Id"? />
??????????? <display:column property="name"? titleKey="struts2Name"? />
??????????? <display:column property="address" title="struts2AddressXX" titleKey="struts2Address" />
??????????? <display:column property="remark" />?????
????????? </display:table>
??????? </fmt:bundle>
??? </body>
</html>
?
- -!
發現杯具了。。。。。。原來之前自己為了漢化displaytag顯示的頁面,所以建過一個displaytag_zh_CN.properties文件。。。
而當中的provider正是我之前嘗試過的I18nStruts2Adapter。。。。。而且I18nStruts2Adapter后面還多打了一個r。。。。
因為瀏覽器的locale是zh_CN,所以它讀取的displaytag_zh_CN.properties,而不是displaytag.properties。。。。
所以就算我使用了默認的jstl解決方案也不能解決,因為配錯了屬性。而之前的I18nStruts2Adapter也寫多了個r。。。
?
搞到兩邊都錯了。。。。。。。。
杯具啊。。。。。。。
改正后,發現jstl起效了。
修改locale后,發現屬性文件都有效果了。。。。。。
再試試在網上找來的I18nStruts2Adapter,發現都能用。。。。
在進行進一步檢查,發現有些導入是多余的,比如<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>,
但是<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>在jstl中是必需的,因為要用到。而如果使用
struts2,則不需要了。
另外屬性文件中的locale.resolver好像不需要配置。
還有?? <fmt:setLocale value="zh_CN"/>好像是用于設置瀏覽器的locale,而屬性文件在你的程序剛開始運行時,好像是根據你
的系統的locale來加載的,所以二者是兩碼事,別弄混了。
到頭來問題終究是解決了~~~~~~~~~~~喵了個咪的~~~~~~~~~~~~
大家如果覺得還有什么問題,可以告訴我。
?
收藏于 2011-03-09總結
以上是生活随笔為你收集整理的displaytag 国际化 探索日志 注释的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CMD如何切换目录
- 下一篇: 车桥耦合非线性振动运动方程求解