如何国际化基本的 JSP/Servlet Web Applications (i18n)

首先,我们将学习如何使用 JSTL Taglib 来本地化 JSP 页面。此外,我们还将演示如何使用请求参数、会话属性和 cookie 值在 JSP 页面中选择首选语言。此外,我们将使用Maven来设置该项目。因此,我们希望读者具备Java Web Application,JSP,JSTL和Maven的基本知识。您可以在 Phrase 的 GitHub 上找到本教程的完整实现。

1. 项目设置

对于这个简单的JSP/Servlet Web应用程序,我们只需要将jstljavax.servlet-api依赖项添加到我们的pom.xml文件中:

<properties>
    <servlet.version>3.1.0</servlet.version>
    <jstl.version>1.2</jstl.version>
</properties>

<dependencies>
    <dependency>
        <groupId>jstl</groupId>
        <artifactId>jstl</artifactId>
        <version>${jstl.version}</version>
    </dependency>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>${servlet.version}</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

我们可以在Maven Central上找到这些依赖项的最新版本:jstljavax.servlet-api

2. 本地化 JSP 页面

本地化 JSP 页面的基本方法是将 JSTL 与资源包结合使用。资源包是包含键值对的属性文件。每个值都是我们要在页面上显示的消息。而密钥将用于在我们的 JSP 页面上引用该值。因此,对于每种支持的语言,我们将有一个特定的属性文件。

现在,让我们在src/main/resources下创建一个默认的消息.属性文件,如下所示:

label.welcome = Welcome

接下来,我们创建一个欢迎.jsp页面,并将其放在 /webapp 文件夹下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ page isELIgnored="false" %>

<fmt:setBundle basename="messages"/>

<html>
<head>
    <title>PhraseApp - i18n</title>
</head>
<body>
    <h2>
        <fmt:message key="label.welcome" />
    </h2>
</body>
</html>

在此页面中,我们使用<fmt:setBundle>标记来设置资源包

因为我们的资源包文件是 messages.properties,所以,我们将 basename 属性的值设置为消息。此外,我们使用<ftm:message>标记来引用属性文件中定义的键。

在应用程序服务器上部署项目(在本例中为端口 8080 的 Tomcat 8.5)并访问欢迎.jsp页面上,我们将看到以下结果:

由于我们没有提到要用于页面的区域设置,因此将使用默认 messages.properties 文件中的消息。

现在,我们尝试通过添加另一个资源包文件来支持法语,该文件messages_fr.properties,如下所示:

label.welcome = Bienvenue

然后,我们修改了 welcome.jsp 页面以使用以下新语言:

.....
<fmt:setLocale value="fr"/>
<fmt:setBundle basename="messages" />
.....

在这里,通过使用<fmt:setLocale>标记将首选区域设置设置为fr,当我们加载页面时,将使用新的messages_fr.properties文件。因此,我们将看到以下结果:

在此之前,我们可以注意到资源包属性文件的名称将具有以下格式:

[basename]_[locale].properties

因此,我们可以通过添加messages_zh.properties和messages_de.properties来支持其他语言,例如中文和德语。

值得注意的是,如果我们将区域设置设置为不存在的资源包文件,则应用程序将使用 messages.properties 文件作为默认显示文件。

3. 动态选择区域设置

我们已经探讨了如何为 JSP 页面设置首选语言环境。如果我们知道如何动态地执行此操作,那将是有用的。在本节中,我们将了解如何使用请求参数、会话属性和浏览器 Cookie 设置页面区域设置。

3.1. 使用请求参数作为区域设置

让我们创建请求Locale.jsp如下所示:

<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ page isELIgnored="false"%>

<fmt:setLocale value="${param.lang}" />
<fmt:setBundle basename="messages" />

<html lang="${param.lang}">
<head>
<title>PhraseApp - i18n</title>
</head>
<body>
	<h2>
            <fmt:message key="label.chooseRequestLocale" />
        </h2>
	<p>
            <fmt:message key="label.requestLocaleContent" />
        </p>
	<p>
            <fmt:message key="label.changeLang" />
        </p>
	<ul>
		<li><a href="?lang=en"><fmt:message key="label.lang.en" /></a></li>
		<li><a href="?lang=de"><fmt:message key="label.lang.de" /></a></li>
		<li><a href="?lang=fr"><fmt:message key="label.lang.fr" /></a></li>
		<li><a href="?lang=zh"><fmt:message key="label.lang.cn" /></a></li>
	</ul>
</body>
</html>

在此页中,我们将区域设置设置为请求参数 lang 的值。因此,当访问参数 lang=zh 的页面时,我们将看到以下结果:

 

3.2. 使用会话属性作为区域设置

同样,要使用 session 属性设置区域设置,我们可以实现 sessionLocale.jsp如下所示:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ page isELIgnored="false" %>
<%@ page session="true" %>

<fmt:setLocale value="${sessionScope.lang}"/>
<fmt:setBundle basename="messages"/>

<html lang="${sessionScope.lang}">
<head>
    <title>PhraseApp - i18n</title>
</head>
<body>
	<h2>
	    <fmt:message key="label.welcome" />
	</h2>
	<p>
            <fmt:message key="label.sessionLocaleContent" />
        </p>
</body>
</html>

在此示例中,我们将 sessionScope 中的属性 lang 称为首选区域设置。

因此,让我们创建一个 SessionLocaleFilter 来更新 session 属性 lang

@WebFilter(filterName = "SessionLocaleFilter", urlPatterns = {"/*"})
public class SessionLocaleFilter implements Filter {
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
      throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        
        if (req.getParameter("sessionLocale") != null) {
            req.getSession().setAttribute("lang", req.getParameter("sessionLocale"));
        }
        chain.doFilter(request, response);
    }
    public void destroy() {}
    public void init(FilterConfig arg0) throws ServletException {}
}

此筛选器将检查请求参数 sessionLocale 是否可用于传入请求。如果是,筛选器会将当前会话的属性 lang 更新为该值。

现在,让我们创建一个 changeLocale.jsp 页面来帮助我们更新此会话属性:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ page isELIgnored="false" %>

<fmt:setLocale value="${param.lang}"/>
<fmt:setBundle basename="messages"/>

<html lang="${param.lang}">
<head>
    <title>PhraseApp - i18n</title>
</head>
<body>
	<h2>
		<fmt:message key="label.chooseSessionLocale" />
	</h2>
	<ul>
		<li><a href="?sessionLocale=en"><fmt:message key="label.lang.en" /></a></li>
		<li><a href="?sessionLocale=de"><fmt:message key="label.lang.de" /></a></li>
		<li><a href="?sessionLocale=fr"><fmt:message key="label.lang.fr" /></a></li>
		<li><a href="?sessionLocale=zh"><fmt:message key="label.lang.cn" /></a></li>
	</ul>
	<c:if test="${not empty param.sessionLocale}">
		<fmt:message key="label.cookieChangeSuccess" />
		<button><a href="sessionLocale.jsp"><fmt:message key="label.viewPage" /></a></button>
	</c:if>
</body>
</html>

Then, we can run the application to access this changeLocale.jsp page and choose the German language. After that, we open our sessionLocale.jsp to see the result as below:

3.3. Using Browser Cookie As Locale

因此,使用相同的方法,我们可以实现一个使用浏览器cookie的值作为区域设置的页面。因此,我们有下面的cookieLocale.jsp页面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ page isELIgnored="false" %>
<%@ page session="true" %>

<fmt:setLocale value="${cookie['lang'].value}"/>
<fmt:setBundle basename="messages"/>

<html lang="${cookie['lang'].value}">
<head>
    <title>PhraseApp - i18n</title>
</head>
<body>
	<h2>
	    <fmt:message key="label.welcome" />
	</h2>
	<p>
            <fmt:message key="label.cookieLocaleContent" />
        </p>
</body>
</html>

假设我们通过键朗将区域设置存储在 Cookie 。因此,我们通过使用表达式 cookie['lang'].value 来访问此 cookie 值。因此,我们的页面将使用该值作为首选区域设置。

此外,我们需要创建一个CookieLocaleFilter,以帮助我们在测试页面之前更改浏览器cookie值:

@WebFilter(filterName = "CookieLocaleFilter", urlPatterns = { "/*" })
public class CookieLocaleFilter implements Filter {

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
      throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;

        if (req.getParameter("cookieLocale") != null) {
            Cookie cookie = new Cookie("lang", req.getParameter("cookieLocale"));
            res.addCookie(cookie);
        }

        chain.doFilter(request, response);
    }

    public void destroy() {}

    public void init(FilterConfig arg0) throws ServletException {}

}

对于每个传入的请求,上面的过滤器将检查参数cookieLocale是否可用。如果是,则其值将设置为带有键 lang 的浏览器 cookie。

同样,让我们更新更改Locale.jsp以允许我们更改此cookie值:

...
        <h2>
		<fmt:message key="label.chooseCookieLocale" />
	</h2>
	<ul>
		<li><a href="?cookieLocale=en"><fmt:message key="label.lang.en" /></a></li>
		<li><a href="?cookieLocale=de"><fmt:message key="label.lang.de" /></a></li>
		<li><a href="?cookieLocale=fr"><fmt:message key="label.lang.fr" /></a></li>
		<li><a href="?cookieLocale=zh"><fmt:message key="label.lang.cn" /></a></li>
	</ul>
	<c:if test="${not empty param.cookieLocale}">
		<fmt:message key="label.cookieChangeSuccess" />
		<button><a href="cookieLocale.jsp"><fmt:message key="label.viewPage" /></a></button>
	</c:if>
...

同样,让我们运行应用程序并打开此更改Locale.jsp选择中文作为cookie区域设置。然后,我们可以访问 cookieLocale.jsp以查看结果:

4. 结论

在本文中,我们探讨了如何在基本的 Java Web 应用程序上本地化 JSP 页面。此外,我们还学习如何通过使用请求参数、会话属性和浏览器 Cookie 动态选择区域设置。

我们的方法是将JSTL与资源包结合使用,我们使用<ftm:setLocale><ftm:setBundle>来引用资源包属性文件。

请查看我们的 Github 存储库,了解本文的完整实现。

如果您对有关 Java Web 应用程序的国际化本地化的高级主题感兴趣,请查看其他博客文章,如 Spring MVC I18N

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值