Почему мой JSP не отображается в немецкой (de_DE) локали при использовании? - PullRequest
1 голос
/ 13 ноября 2010

Я создал следующую 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

    }

}

Есть идеи, почему я вижу английский и как это исправить?

1 Ответ

1 голос
/ 13 ноября 2010

Есть 2 проблемы:

Во-первых, fmt:setLocale TLDDOC говорит следующее:

value - java.lang.String - A String значение интерпретируется как печатное представление локали, которое должно содержать двухбуквенный (строчный) языковой код (как определено в ISO-639) и может содержать двухбуквенное (верхнийcase) код страны (как определено ISO-3166).Коды языка и страны должны быть разделены дефисом (-) или подчеркиванием (_).

Другими словами, вы не можете установить его с помощью java.util.Locale.

Во-вторых, все, что было объявлено с использованием скриптлетов , недоступно вEL.EL может получить доступ только к атрибутам, которые были помещены в PageContext, HttpServletRequest, HttpSession или ServletContext его методом setAttribute().Под крышками EL в основном делает pageContext.findAttribute(name) для ${name}.Существует в основном 4 решения в порядке от наименьшей до наилучшей рекомендации:

  1. Использование скриптлет вместо EL в <fmt:setLocale>.
  2. Поместить локаль в область запросаrequest.setAttribute("locale", locale); внутри скриптлет .
  3. избавиться от скриптлетов и объявить LanguageToolkit как функцию EL.
  4. Создайте Filter, который выполняет эту работу.

Тем не менее, я бы рекомендовал использовать <fmt:setBundle> вместо <fmt:bundle> в данном конкретном случае, посколькуВы, кажется, хотите охватить всю страницу.Я бы также рекомендовал использовать HttpServletRequest#getLocale() вместо ручного анализа заголовка запроса.Правильный алгоритм является более сложным, чем тот, который у вас есть.

...