2010-11-13 42 views
1

我创建了下面的JSP:当我使用<fmt:setLocale>时,为什么我的JSP不会在德语(de_DE)语言环境中显示?

<!-- 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> 

当我尝试这个网址访问该网页:

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

有2个问题:

首先,fmt:setLocale TLDDOC说以下内容:

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

换句话说,您不能将其设置为java.util.Locale。其次,使用scriptlets声明的任何内容都不能在EL中访问。 EL只能通过其setAttribute()方法访问已放置在PageContext,HttpServletRequest,HttpSessionServletContext中的属性。在封面下,EL基本上为${name}做了pageContext.findAttribute(name)。基本上有4个解决办法,以便从低到最好的建议:

  1. 使用scriptlet而代替EL的<fmt:setLocale>
  2. 将请求范围内的语言环境放在request.setAttribute("locale", locale);之内scriptlet
  3. Get ridscriptlets并声明LanguageToolkit作为EL功能。
  4. 创建一个Filter从事这项工作。

这就是说,我会建议在这种特殊情况下使用<fmt:setBundle>而不是<fmt:bundle>因为你似乎要覆盖整个页面。我还建议使用HttpServletRequest#getLocale()而不是手动分析请求标头。正确的算法比迄今为止更复杂。

+0

我没有真正地遵循上述。如果我使用,我会得到我期待的结果。如果我输出变量“locale”(有或没有显式地添加“.toString()”,值是“de_DE”。所以,我没有看到有什么区别......并且我不确定是什么你的意思是关于使用scriptlet(s),也不是HttpServletRequest#getLocale()....如果你有时间,你可以为我打破这件事吗? – 2010-11-13 14:16:05

+0

我设法使解决方案#2工作...仍然会好奇以实施其他解决方案,特别是更好的解决方案。:-) – 2010-11-13 14:31:12

+1

Scriptlets是那些老式的'<% %>'事物。 EL是现代的'$ {}'的东西。他们不共享相同的变量范围。点击“摆脱”链接了解更多信息。 – BalusC 2010-11-13 14:43:55