8.3.1 Web程序国际化的原理
国际化程序需要通过Locale对象确定具体的本地信息。在Web程序中,可以通过HttpServletRequest类的getLocale方法获得客户端浏览器支持的首选本地信息(Locale对象)。在8.2.1节讲过,创建Locale对象需要指定语言和国家。在Web程序中这些信息一般是由HTTP请求消息头的Accept-Language字段指定的。
查看浏览器发给服务端的Accept-Language字段的内容的方法有很多。在这里我推荐使用HTTP监视软件(如HTTP Analyzer)来截获HTTP请求消息头。读者可以在浏览器中访问任何一个本地或Internet上的网址,如http://nokiaguy.blogjava.net,HTTP Analyzer截获的HTTP请求消息头如图8.10所示。
图8.10 HTTP请求消息头
从图8.10所示的HTTP请求消息头可以看出,Accept-Language字段的内容如下:
Accept-Language:zh-cn,en-us;q=0.5
浏览器支持的所有本地信息都包含在Accept-Language字段中,如果有多个本地信息,中间用逗号(,)分隔。HttpServletRequest类的getLocale方法会根据这些信息返回相应的Locale对象。实际上,Accept-Language字段的信息和浏览器的设置有关,在IE浏览器中通过单击【工具】>【Internet 选项】菜单项打开【Internet 选项】对话框,单击【语言】按钮打开【语言首选项】对话框。Accept-Language字段的值就是在【语言首选项】对话框中设置的值。在我的机器上的【语言首选项】对话框如图8.11所示。
图8.11 【语言首选项】对话框
如果使用图8.11所示的设置,在访问服务端资源时,IE发送的HTTP请求消息头中的Accept-Language字段值就会图8.10所示的Accept-Language字段值相同。
HttpServletRequest类除了getLocale方法外,还有一个getLocales方法用来获得客户端支持的所有本地信息。下面的程序列出了客户端浏览器的首选本地信息和支持的所有本地信息:
package chapter8.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Locale;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ListClientLocale extends HttpServlet
{
protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOExceptio
{
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
Locale locale = request.getLocale();
out.println("首选的语言和国家<p/>");
out.println("语言:" + locale.getLanguage() + "<br>");
out.println("国家:" + locale.getCountry() + "<hr>");
out.println("客户端浏览器支持的所有本地信息列表,按优先级的高级排序<p/>");
Enumeration<Locale> allLocale = request.getLocales();
while(allLocale.hasMoreElements())
{
Locale loc = allLocale.nextElement();
out.println(loc.getLanguage() + "-" + loc.getCountry() + "<br>");
}
}
}
ListClientLocale的配置代码如下:
<servlet>
<servlet-name>ListClientLocale</servlet-name>
<servlet-class>chapter8.servlet.ListClientLocale</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ListClientLocale</servlet-name>
<url-pattern>/chapter8/ListClientLocale</url-pattern>
</servlet-mapping>
在浏览器地址栏中输入如下的URL:
http://localhost:8080/demo/chapter8/ListClientLocale
浏览器显示的输出结果如图8.12所示。
图8.12 显示客户端的首选本地信息和支持的所有本地信息
如果将8.11所示的两个本地信息调换,再次访问上面的URL,将会得到如图8.13所示的输出结果。
图8.13 显示客户端的首选本地信息和支持的所有本地信息
从图8.13所示的输出结果可以看出,首选的本地信息变成了英文(美国),而浏览器支持的所有本地信息的顺序也变化了。