How to internationalize basic JSP/Servlet Web Applications (i18n)

First, we will learn how to use JSTL Taglib to localize JSP pages. In addition, we will demonstrate how to use request parameters, session attributes and cookie values to select the preferred language in JSP pages. In addition, we will use Maven to set up the project. Therefore, we hope readers have the basic knowledge of Java Web Application, JSP, JSTL and Maven. You can use Phrase's GitHub Find the complete implementation of this tutorial on.

content

1. Project setting

For this simple JSP/Servlet Web application, we only need to combine jstl and javax Servlet API dependency added to our POM XML file:

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

We can find the latest versions of these dependencies on Maven Central: jstljavax.servlet-api

2. Localized JSP pages

The basic way to localize JSP pages is to use JSTL in combination with resource packs. A resource package is a property file that contains key value pairs. Each value is the message we want to display on the page. The key will be used to reference the value on our JSP page. Therefore, for each supported language, we will have a specific properties file.

Now, let's create a default message under src/main/resources Properties file, as follows:

label.welcome = Welcome

Next, we create a welcome jsp page and put it under the / webapp # folder:

<%@ 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>

On this page, we use the < FMT: setbundle > tag to set the resource package.

Because our resource package file is messages Properties, so we set the value of the {basename} property to message. In addition, we use the < FTM: Message > tag to refer to the keys defined in the properties file.

Deploy the project on the application server (Tomcat 8.5 on port 8080 in this case) and visit welcome jsp page, we will see the following results:

Since we didn't mention the locale to use for the page, we'll use the default message Messages in the properties file.

Now let's try to support French by adding another resource pack file, messages_fr.properties, as follows:

label.welcome = Bienvenue

Then, we modified , welcome JSP page to use the following new language:

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

Here, the preferred locale is set to fr by using the < FMT: setlocale > tag, and the new messages will be used when we load the page_ Fr.properties file. Therefore, we will see the following results:

Before that, we can notice that the name of the resource package properties file will have the following format:

[basename]_[locale].properties

Therefore, we can add messages_zh.properties and messages_de.properties to support other languages, such as Chinese and German.

It is worth noting that if we set the locale to a nonexistent resource package file, the application will use {messages The properties file is used as the default display file.

3. Dynamic selection of regional settings

We have explored how to set the preferred locale for JSP pages. It would be useful if we knew how to do this dynamically. In this section, we will learn how to set the page locale using request parameters, session properties, and browser cookies.

3.1. Use request parameters as locale

Let's create the request locale JSP is as follows:

<%@ 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>

On this page, we set the locale to the value of the request parameter {Lang. Therefore, when accessing the page with parameter lang=zh, we will see the following results:

 

3.2. Use session properties as locale

Similarly, to use the session property to set the locale, we can implement sessionlocale JSP is as follows:

<%@ 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>

In this example, we call the attribute lang in sessionScope the preferred locale.

Therefore, let's create a session localefilter to update the session attribute 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 {}
}

This filter checks whether the request parameter 'sessionLocale' is available for incoming requests. If yes, the filter updates the current session's property lang to this value.

Now, let's create a changelocale JSP page to help us update the session properties:

<%@ 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

Therefore, using the same method, we can implement a page that uses the value of the browser cookie as the locale. Therefore, we have the following cookielocale JSP page:

<%@ 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>

Suppose we store the locale in a cookie #. Therefore, we use the expression "cookie ['lang '] Value to access this cookie value. Therefore, our page will use this value as the preferred locale.

In addition, we need to create a cookie localefilter to help us change the browser cookie value before testing the page:

@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 {}

}

For each incoming request, the above filter checks whether the parameter cookieLocale is available. If so, its value will be set to a browser cookie with the key {lang}.

Similarly, let's update and change locale JSP to allow us to change this cookie value:

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

Similarly, let's run the application and open this change locale JSP selects Chinese as the cookie locale. Then, we can visit # cookielocale JSP to view the results:

4. Conclusion

In this article, we explored how to localize JSP pages on basic Java Web applications. In addition, we learned how to dynamically select locales by using request parameters, session properties, and browser cookies.

Our method is to combine JSTL with resource package. We use < FTM: setlocale > and < FTM: setbundle > to reference the resource package attribute file.

Please check our Github Repository to understand the complete implementation of this article.

If you have questions about Java Web Applications internationalization and localization Interested in advanced topics, please check other blog posts, such as Spring MVC I18N.

Keywords: Java Maven

Added by almightyegg on Mon, 07 Mar 2022 06:17:43 +0200