Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>In case of a basic JSP/Servlet webapplication, the basic approach would be using <a href="http://docs.oracle.com/javaee/5/jstl/1.1/docs/tlddocs/" rel="noreferrer">JSTL</a> <a href="http://docs.oracle.com/javaee/5/jstl/1.1/docs/tlddocs/fmt/tld-summary.html" rel="noreferrer"><code>fmt</code> taglib</a> in combination with <a href="http://docs.oracle.com/javase/tutorial/i18n/resbundle/index.html" rel="noreferrer">resource bundles</a>. Resource bundles contain key-value pairs where the key is a constant which is the same for all languages and the value differs per language. Resource bundles are usually <a href="http://docs.oracle.com/javase/tutorial/essential/environment/properties.html" rel="noreferrer">properties files</a> which are loaded by <a href="http://docs.oracle.com/javase/6/docs/api/java/util/ResourceBundle.html" rel="noreferrer"><code>ResourceBundle</code></a> API. This can however be customized so that you can load the key-value pairs from for example a database.</p> <p>Here's an example how to internationalize the login form of your webapplication with properties file based resource bundles.</p> <hr> <ol> <li><p>Create the following files and put them in some package, e.g. <code>com.example.i18n</code> (in case of Maven, put them in the package structure inside <code>src/main/resources</code>).</p> <p><code>text.properties</code> (contains key-value pairs in the default language, usually English)</p> <pre> login.label.username = Username login.label.password = Password login.button.submit = Sign in </pre> <hr> <p><code>text_nl.properties</code> (contains Dutch (<code>nl</code>) key-value pairs)</p> <pre> login.label.username = Gebruikersnaam login.label.password = Wachtwoord login.button.submit = Inloggen </pre> <hr> <p><code>text_es.properties</code> (contains Spanish (<code>es</code>) key-value pairs)</p> <pre> login.label.username = Nombre de usuario login.label.password = Contraseña login.button.submit = Acceder </pre> <p>The resource bundle filename should adhere the following pattern <code>name_ll_CC.properties</code>. The <code>_ll</code> part should be the lowercase <a href="http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes" rel="noreferrer">ISO 693-1</a> language code. It is optional and only required whenever the <code>_CC</code> part is present. The <code>_CC</code> part should be the uppercase <a href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2" rel="noreferrer">ISO 3166-1 Alpha-2</a> country code. It is optional and often only used to distinguish between country-specific language dialects, like <a href="http://en.wikipedia.org/wiki/American_English" rel="noreferrer">American English</a> (<code>_en_US</code>) and <a href="http://en.wikipedia.org/wiki/British_English" rel="noreferrer">British English</a> (<code>_en_GB</code>).</p> <hr></li> <li><p>If not done yet, install JSTL. If you're running on a Servlet 2.5 container or newer (Tomcat 6.0 and so on) and your <code>web.xml</code> is declared conform the Servlet 2.5 specification, then just put <a href="http://central.maven.org/maven2/javax/servlet/jstl/1.2/jstl-1.2.jar" rel="noreferrer">jstl-1.2.jar</a> in webapp's <code>/WEB-INF/lib</code> folder.</p> <hr></li> <li><p>Create the following example JSP file and put it in web content folder.</p> <p><code>login.jsp</code></p> <pre class="lang-xml prettyprint-override"><code>&lt;%@ page pageEncoding="UTF-8" %&gt; &lt;%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %&gt; &lt;%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %&gt; &lt;c:set var="language" value="${not empty param.language ? param.language : not empty language ? language : pageContext.request.locale}" scope="session" /&gt; &lt;fmt:setLocale value="${language}" /&gt; &lt;fmt:setBundle basename="com.example.i18n.text" /&gt; &lt;!DOCTYPE html&gt; &lt;html lang="${language}"&gt; &lt;head&gt; &lt;title&gt;JSP/JSTL i18n demo&lt;/title&gt; &lt;/head&gt; &lt;body&gt; &lt;form&gt; &lt;select id="language" name="language" onchange="submit()"&gt; &lt;option value="en" ${language == 'en' ? 'selected' : ''}&gt;English&lt;/option&gt; &lt;option value="nl" ${language == 'nl' ? 'selected' : ''}&gt;Nederlands&lt;/option&gt; &lt;option value="es" ${language == 'es' ? 'selected' : ''}&gt;Español&lt;/option&gt; &lt;/select&gt; &lt;/form&gt; &lt;form method="post"&gt; &lt;label for="username"&gt;&lt;fmt:message key="login.label.username" /&gt;:&lt;/label&gt; &lt;input type="text" id="username" name="username"&gt; &lt;br&gt; &lt;label for="password"&gt;&lt;fmt:message key="login.label.password" /&gt;:&lt;/label&gt; &lt;input type="password" id="password" name="password"&gt; &lt;br&gt; &lt;fmt:message key="login.button.submit" var="buttonValue" /&gt; &lt;input type="submit" name="submit" value="${buttonValue}"&gt; &lt;/form&gt; &lt;/body&gt; &lt;/html&gt; </code></pre> <p>The <code>&lt;c:set var="language"&gt;</code> manages the current language. If the language was supplied as request parameter (by language dropdown), then it will be set. Else if the language was already previously set in the session, then stick to it instead. Else use the user supplied locale in the request header.</p> <p>The <code>&lt;fmt:setLocale&gt;</code> sets the locale for resource bundle. It's important that this line is <em>before</em> the <code>&lt;fmt:setBundle&gt;</code>.</p> <p>The <code>&lt;fmt:setBundle&gt;</code> initializes the resource bundle by its base name (that is, the full qualified package name until with the sole name without the <code>_ll_CC</code> specifier).</p> <p>The <code>&lt;fmt:message&gt;</code> retrieves the message value by the specified bundle key.</p> <p>The <code>&lt;html lang="${language}"&gt;</code> informs the searchbots what language the page is in so that it won't be marked as duplicate content (thus, good for SEO).</p> <p>The language dropdown will immediately submit by JavaScript when another language is chosen and the page will be refreshed with the newly chosen language.</p></li> </ol> <hr> <p>You however need to keep in mind that properties files are by default read using ISO-8859-1 character encoding. You would need to escape them by unicode escapes. This can be done using the JDK-supplied <code>native2ascii.exe</code> tool. See also <a href="http://balusc.blogspot.com/2009/05/unicode-how-to-get-characters-right.html#JavaPropertiesFiles" rel="noreferrer">this article section</a> for more detail. </p> <p>A theoretical alternative would be to supply a bundle with a custom <a href="http://docs.oracle.com/javase/6/docs/api/java/util/ResourceBundle.Control.html" rel="noreferrer"><code>Control</code></a> to load those files as UTF-8, but that's unfortunately not supported by the basic JSTL <code>fmt</code> taglib. You would need to manage it all yourself with help of a <code>Filter</code>. There are (MVC) frameworks which can handle this in a more transparent manner, like JSF, see also <a href="http://jdevelopment.nl/java/internationalization-jsf-utf8-encoded-properties-files/" rel="noreferrer">this article</a>.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload