1

我创建了以下 JSP:

<!-- WebContent/pages/ResourceBundlesJST.jsp -->
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ page import="java.text.*" %>
<%@ page import="java.util.*" %>
<%@ page import="hu.flux.locale.LanguageToolkit" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%  
    Locale locale = LanguageToolkit.getLanguage(request);
    //String locale = LanguageToolkit.getLanguageString(request);
%>
<fmt:setLocale value="${locale}" />
<fmt:bundle basename="hu.flux.locale.resources.TestResources">
    <!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=ISO-8859-1">
    <title>Insert title here</title>
    </head>
    <body>
        <h1><fmt:message key="greetHeading"/></h1>
        <p><fmt:message key="welcomeText"/></p>
        <p>Your locale is <%= locale %>.</p>
        <form action="your_form_handler_here" method="post">
            <div>
                <label for="name"><fmt:message key="namePrompt"/></label>
                <input type="text" id="name" name="name">
            </div>
            <div>
                <label for="age"><fmt:message key="agePrompt"/></label>
                <input type="text" id="age" name="age">
            </div>
            <div>
                <label for="place"><fmt:message key="placePrompt"/></label>
                <input type="text" id="place" name="place">
            </div>
            <input type="submit" value="<fmt:message key="submitButtonText"/>">
        </form>
    </body>
    </html>
</fmt:bundle>

当我尝试使用此 URL 访问页面时:

http://localhost:8080/SamsTeachYourselfJSP/pages/ResourceBundlesJSTL.jsp?languageOverride=de_DE

这将显示在屏幕上:

Hello!

Welcome to our web site. Please take a moment to fill out our survey

Your locale is de_DE.

What is your name:  
How old are you:  
Where do you live:  

尽管服务器选择了我的参数将语言环境设置为 de_DE 并接受了设置语言环境的命令,但该页面显然正在查找并使用英语属性文件而不是德语属性文件。

我希望它调用的资源包含:

# /src/hu/flux/locale/resources/TestResources_de.properties
namePrompt=Wie hei[gb]en Sie:
agePrompt=Wie alt sind Sie:
placePrompt=Wo wohnen Sie:
greetHeading=Guten Tag!
welcomeText= Willkommen bei unserer Web-Site.  Bitte, dauern Sie einen Moment Um unsere Umfrage auszufüllen
submitButtonText=Senden

我很确定问题不在我的 LanguageToolkit 类中,因为它适用于此页面的非 JSTL 版本,但如果有人想查看它:

/**
 * /src/hu/flux/locale/LanguageToolkit.java
 */
package hu.flux.locale;

import java.util.Locale;
import java.util.StringTokenizer;

import javax.servlet.http.HttpServletRequest;

/**
 * @author Brian Kessler
 *
 */
public class LanguageToolkit {

    /**
     * 
     */
    public LanguageToolkit() {
        // TODO Auto-generated constructor stub
    }

    public static Locale getLanguage(HttpServletRequest request)
    {
        Locale locale = Locale.getDefault();

        // Get the browser's preferred language.
        String acceptLangString = request.getHeader("ACCEPT-LANGAUGE");

        // Allow the user to override the browser's langauge setting.
        // This lets you test with tools such as Babelfish 
        // (which isn't that great at translating to begin with).
        String override = request.getParameter ("languageOverride");
        if (override != null) { acceptLangString = override; }

        // If there is an ACCEPT-LANGUAGE header, parse it.
        if (acceptLangString != null) 
        {  
            Locale acceptedLocale = parseLangString (acceptLangString);
            if (acceptedLocale != null) {locale = acceptedLocale;}
        }

        return locale;
    }

    public static String getLanguageString(HttpServletRequest request)
    {
        String locale = "EN-uk";

        // Get the browser's preferred language.
        String acceptLangString = request.getHeader("ACCEPT-LANGAUGE");

        // Allow the user to override the browser's langauge setting.
        // This lets you test with tools such as Babelfish 
        // (which isn't that great at translating to begin with).
        String override = request.getParameter ("languageOverride");
        if (override != null) { acceptLangString = override; }

        // If there is an ACCEPT-LANGUAGE header, parse it.
        if (acceptLangString != null)  {locale = acceptLangString;}

        return locale;
    }

    private static Locale parseLangString(String acceptLangString) 
    {
        // The accepted languages should be separated by commas, but also
        // add space as a separator to eliminate whitespace.
        StringTokenizer localeParser = new StringTokenizer(acceptLangString, " ,");

        // See whether there is a language in the list (you need only the first one).
        if (localeParser.hasMoreTokens())
        {
            // Get the locale.
            String localeStr = localeParser.nextToken();

            // The local should be in the format ll-CC where 11 is the language
            // and CC is the country, like en-US for English in the U.S. and
            // de-DE for German in Germany.  Allow the browser to use _ instead
            // of -, too.
            StringTokenizer localeSplitter = new StringTokenizer (localeStr, "_-");

            // Assume both values are blank.
            String language = "";
            String country = "";

            // See whether a language is specified.
            if (localeSplitter.hasMoreTokens()) {language = localeSplitter.nextToken(); }

            // See whether a country is specified (there won't always be one).
            if (localeSplitter.hasMoreTokens()) {country = localeSplitter.nextToken(); }

            // Create a local based on this language and country (if country is blank,
            // you'll still get locale-based text, but currencies won't display correctly.
            return (new Locale(language, country));
        }
        return null;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

    }

}

任何想法为什么我看到英语以及如何解决它?

4

1 回答 1

1

有2个问题:

首先,fmt:setLocaleTLDDOC说明如下:

value- java.lang.String-字符串值被解释为区域设置的可打印表示,它必须包含两个字母(小写)的语言代码(由 ISO-639 定义),并且可能包含两个字母(大写)国家代码(由 ISO-3166 定义)。语言和国家代码必须用连字符 (-) 或下划线 (_) 分隔。

换句话说,你不能用java.util.Locale.

其次,任何使用scriptlet声明的东西都不能在 EL 中访问。EL 只能访问放置在PageContextHttpServletRequestHttpSession或其方法中ServletContext的属性setAttribute()。在幕后,EL 基本上是pageContext.findAttribute(name)为 a 做 a ${name}。基本上有 4 种解决方案,按照从最低到最好的推荐顺序排列:

  1. <fmt:setLocale>. _ _
  2. request.setAttribute("locale", locale);通过内部scriptlet将语言环境置于请求范围内。
  3. 摆脱scriptlet并声明为LanguageToolkitEL 函数。
  4. 创建一个Filter可以完成工作的。

也就是说,我建议在这种特殊情况下使用<fmt:setBundle>而不是,<fmt:bundle>因为您似乎想要覆盖整个页面。我还建议使用HttpServletRequest#getLocale()而不是手动解析请求标头。正确的算法比您目前所掌握的更复杂。

于 2010-11-13T12:18:10.797 回答