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>
 * &lt;display:column titleKey="bar"/>
 * </pre>
 *
 * behave the same as
 *
 * <pre>
 * &lt;c:set var="foo">
 *   &lt;fmt:message key="bar"/>
 * &lt;/c:set>
 * &lt;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来加载的,所以二者是两码事,别弄混了。


到头来问题终究是解决了~~~~~~~~~~~喵了个咪的~~~~~~~~~~~~


大家如果觉得还有什么问题,可以告诉我。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值