Java 11,Spring Boot和JavaScript中的i18n

什么是i18n和l10n? 国际化(i18n)是提出申请的过程能用多种语言呈现文本的过程。 本地化(l10n)表示您的应用程序已按照满足特定语言环境的语言,文化或其他要求的方式进行了编码。 这些要求可以包括日期,时间和货币的格式,以及符号,图标和颜色等。 i18n启用l10n。

为什么i18n和l10n重要? 因为您想让您的应用程序可供尽可能多的用户访问! 如果您以英语为母语,那么您会被宠坏了,因为英语目前是商务语言,并且许多应用程序都提供英语翻译。 借助内置机制,国际化Java应用程序相对简单。 Spring Boot也是如此-默认情况下存在!

本教程将向您展示如何国际化简单的Java应用程序,带有Thymeleaf的Spring Boot应用程序以及JavaScript窗口小部件。

Java i18n with Resource Bundles

一种资源包是一个.properties file that contains keys and values for specific languages. Using 资源包s allows you to make your code locale-independent. To see how this works, create a new directory on your hard drive for this tutorial’s exercises. For example, java-i18n-example。 从命令行导航到该目录并创建一个你好文件。

public class Hello {

    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

跑Java Hello.java并且您应该看到“你好,世界!” 打印到您的控制台。

If you see any error similar to the one below, it’s because you’re using a Java version < 11. JEP 330 is an enhancement in Java 11 that allows you to run a single file of Java source code, without compiling it.

$ java Hello.java
Error: Could not find or load main class Hello.java

You can install Java 11 from AdoptOpenJDK 11 or use SDKMAN!

curl -s "https://get.sdkman.io" | bash

安装SDKMAN之后,您可以列出可用的Java版本,其中包括sdk列表java:

$ sdk list java
================================================================================
Available Java Versions
================================================================================
     13.ea.07-open 8.0.202-zulu
     12.ea.31-open 8.0.202-amzn
   + 11.ea.26-open 8.0.202.j9-adpt
     11.0.2-sapmchn 8.0.202.hs-adpt
     11.0.2-zulu 8.0.202-zulufx
   * 11.0.2-open 8.0.201-oracle
     11.0.2.j9-adpt > + 8.0.181-zulu
     11.0.2.hs-adpt 7.0.181-zulu
     11.0.2-zulufx 1.0.0-rc-12-grl
   + 11.0.1-open 1.0.0-rc-11-grl
   + 11.0.0-open 1.0.0-rc-10-grl
     10.0.2-zulu 1.0.0-rc-9-grl
     10.0.2-open 1.0.0-rc-8-grl
     9.0.7-zulu
     9.0.4-open

================================================================================
+ - local version
* - installed
> - currently in use
================================================================================

使用以下命令将您的环境设置为使用最新版本的OpenJDK:

sdk default java 11.0.2-open

现在您应该可以运行你好作为Java程序。

$ java Hello.java
Hello, World!

妈你看 无需编译! 😃

创建一个messages_zh_CN。properties文件放在同一目录中,并添加术语的键和翻译你好和世界。

hello=Hello
world=World

创建messages_es.properties并用西班牙语翻译填充它。

hello=Hola
world=Mundo

修改你好使用区域设置和资源束从这些文件中检索翻译。

import java.util.Locale;
import java.util.ResourceBundle;

public class Hello {

    public static void main(String[] args) {
        String language = "en";
        String country = "US";

        if (args.length == 2) {
            language = args[0];
            country = args[1];
        }

        var locale = new Locale(language, country);
        var messages = ResourceBundle.getBundle("messages", locale);

        System.out.print(messages.getString("hello") + " ");
        System.out.println(messages.getString("world"));
    }
}

再次运行Java程序,您应该看到“ Hello World”。

$ java Hello.java
Hello World

改进参数的解析,以仅允许指定语言。

if (args.length == 1) {
    language = args[0];
} else if (args.length == 2) {
    language = args[0];
    country = args[1];
}

使用以下命令运行相同的命令es参数,您会看到西班牙语翻译:

$ java Hello.java esHola Mundo

耶eh! Java内置了i18n真的很酷,是吗?

Internationalization with Spring Boot and Thymeleaf

Spring Boot has i18n built-in thanks to the Spring Framework and its MessageSource implementations. There’s a ResourceBundleMessage小号ource that builds on ResourceBundle, as well as a ReloadableResourceBundleMessageSource that should be self-explanatory.

注入讯息来源放入Spring bean并调用getMessage(key,args,locale)满足您的需求! 使用讯息来源将在服务器上为您提供帮助,但是在您的UI中呢? 让我们创建一个快速的应用程序,向您展示如何使用Thymeleaf添加国际化。

Go to start.spring.io and select Web and Thymeleaf as dependencies. Click Generate Project and download the resulting demo.zip file. If you’d rather do it from the command line, you can use HTTPie to do the same thing.

mkdir bootiful-i18n
cd bootiful-i18n
http https://start.spring.io/starter.zip dependencies==web,thymeleaf -d | tar xvz

在您喜欢的IDE中打开项目并创建HomeController。java在src / main / java / com / example / demo。

package com.example.demo;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {

    @GetMapping("/")
    String home() {
        return "home";
    }
}

在以下位置创建Thymeleaf模板src / main / resources / templates / home.html这将呈现“主页”视图。

<html xmlns:th="http://www.thymeleaf.org">
<body>
    <h1 th:text="#{title}"></h1>
    <p th:text="#{message}"></p>
</body>
</html>

添加一个messages.properties归档在src / main / resources定义您的默认语言(在这种情况下为英语)。

title=Welcome
message=Hello! I hope you're having a great day.

在同一目录中的messages_es.properties文件。

title=Bienvenida
message=¡Hola! Espero que estas teniendo un gran día. 😃

Spring Boot uses Spring’s LocaleResolver and (by default) its AcceptHeaderLocalResolver implementation. If your browser sends an accept-language header, Spring Boot will try to find messages that match.

要对其进行测试,请打开Chrome,然后输入chrome:// settings / languages在地址栏中。 展开顶部的“语言”框,单击添加语言并搜索“西班牙语”。 添加不带国家/地区的选项,然后将其移动到使用偏好的首选语言中。 完成后,它应该看起来像下面的屏幕截图。

Chrome Languages

对于Firefox,请导航至关于:首选项,向下滚动到“语言和外观”,然后点击选择 button next to "选择 your preferred language for displaying pages." Select 西班牙文并将其移到顶部。

Firefox Languages

将浏览器设置为返回西班牙语后,请使用./mvnw spring-boot:运行(要么mvnw spring-boot:运行如果您使用的是Windows)。

小费:加<defaultGoal>spring-boot:run</defaultGoal>在里面<build>您的部分pom.xml如果您只想输入./mvnw启动您的应用。

导航http://本地主机:8080并且您应该会看到一个包含西班牙语单词的页面。

Home in Spanish

Add the Ability to Change Locales with a URL Parameter

这是一个不错的设置,但是您可能希望允许用户设置自己的语言。 您可能在狂野的网站上看到了这种情况,它们上面有一个标志,您可以单击该标志以更改为该国家的语言。 为了在Spring Boot中实现这一点,请创建一个MvcConfigurer和你一起上课家庭控制器。

package com.example.demo;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;

@Configuration
public class MvcConfigurer implements WebMvcConfigurer {

    @Bean
    public LocaleResolver localeResolver() {
        return new CookieLocaleResolver();
    }

    @Bean
    public LocaleChangeInterceptor localeInterceptor() {
        LocaleChangeInterceptor localeInterceptor = new LocaleChangeInterceptor();
        localeInterceptor.setParamName("lang");
        return localeInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(localeInterceptor());
    }
}

本课程使用CookieLocaleResolver这对于将区域设置首选项保存在Cookie中以及默认设置为接受语言标头(如果不存在)。

重新启动服务器,您应该可以通过以下方式覆盖浏览器的语言首选项:http:// localhost:8080 /?lang = zh-CN。

Overriding the browser’s language preference

您的语言偏好设置将保存在Cookie中,因此,如果您导航回http://本地主机:8080,页面将以英语呈现。 如果退出浏览器并重新启动,您将返回使用浏览器的语言首选项。

Hot Reloading Thymeleaf Templates and Resource Bundles in Spring Boot 2.1

If you’d like to modify your Thymeleaf templates and see those changes immediately when you refresh your browser, you can add Spring Boot’s Developer Tools to your pom.xml.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
</dependency>

如果您设置了IDE来保存文件时复制资源,那么这就是您需要做的所有事情。 如果您不使用IDE,则需要在自己的文件中定义属性application.properties:

spring.thymeleaf.prefix=file:src/main/resources/templates/

要将更改热加载到i18n捆绑包中,您需要重建项目(例如,通过运行。/mvnw编译)。 如果您使用的是Eclipse,则应自动进行重建和重新启动。 如果您使用的是IntelliJ IDEA,则需要进入运行配置并将“停用框架上”更改为更新资源。

Update resources in IntelliJ IDEA

See this 小号tack Overflow answer for more information.

Customize the Language used by Okta’s Sign-In Widget

The last example I’d like to show you is a Spring Boot app with Okta’s embedded Sign-In Widget. The Sign-In Widget is smart enough to render the language based on your browser’s accept-language header.

但是,如果您想将其与Spring应用程序的LocalResolver,您需要做更多配置。 此外,您可以自定义内容,以便它可以通过Okta用户的语言环境设置来设置语言环境。

首先,导出Spring Boot的自定义登录示例:

svn export https://github.com/okta/samples-java-spring/trunk/custom-login

ŤIP: If you don’t have svn installed, go here and click the Download button.

Create an OIDC App on Okta

If you already have an Okta Developer account, log in to it. If you don’t, create one. After you’re logged in to your Okta dashboard, complete the following steps:

  1. 来自应用领域页面,选择添加申请。在“创建新应用程序”页面上,选择网页。给您的应用起一个令人难忘的名称,然后单击完成。

您的设置应类似于以下设置。

OIDC Web App on Okta

您可以指定您的发行人(位于API > 授权服务器),客户端ID和客户端机密custom-login / src / main / resources / application.yml如下:

okta:
  oauth2:
    issuer: https://{yourOktaDomain}/oauth2/default
    client-id: {yourClientID}
    client-secret: {yourClientSecret}

但是,如果将这些值存储在环境变量中并使其不受源代码控制(尤其是代码公开的情况),则更加安全。

export OKTA_OAUTH2_ISSUER=https://{yourOktaDomain}/oauth2/default
export OKTA_OAUTH2_CLIENT_ID={yourClientID}
export OKTA_OAUTH2_CLIENT_SECRET={yourClientSecret}

小费:我建议将上述出口添加到.okta.env文件放在项目的根目录并添加* .env至.gitignore。 然后跑源.okta.env在启动应用程序之前。

进行这些更改后,您可以使用./mvnw。 打开浏览器http://本地主机:8080,点击登录并且您应该能够进行身份验证。 如果您仍然将浏览器设置为首先使用西班牙语,则会看到“登录小部件”会自动以西班牙语呈现。

Sign-In Widget in Spanish

之所以有效,是因为Spring自动启用AcceptHeaderLocaleResolver。

Add i18n Messages and Sync Locales

它好像就像现在事情进展顺利。 但是,如果您添加一个LocaleChangeInterceptor,您会看到更改语言不会更改小部件的语言。 要查看实际效果,请创建一个MvcConfigurer上课custom-login / src / main / java / com / okta / spring / example。

package com.okta.spring.example;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;

@Configuration
public class MvcConfigurer implements WebMvcConfigurer {

    @Bean
    public LocaleResolver localeResolver() {
        return new CookieLocaleResolver();
    }

    @Bean
    public LocaleChangeInterceptor localeInterceptor() {
        LocaleChangeInterceptor localeInterceptor = new LocaleChangeInterceptor();
        localeInterceptor.setParamName("lang");
        return localeInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(localeInterceptor());
    }
}

Restart the custom-login app and navigate to http://localhost:8080/?lang=en. If you click the login button, you’ll see that the widget is still rendered in Spanish. To fix this, crack open LoginController and add language as a model attribute, and add a Locale parameter to the login() method. Spring MVC will resolve the Locale automatically with ServletRequestMethodArgumentResolver.

package com.okta.spring.example.controllers;

import org.springframework.web.servlet.LocaleResolver;
...

@Controller
public class LoginController {

    ...
    private static final String LANGUAGE = "language";

    private final OktaOAuth2Properties oktaOAuth2Properties;
    private final LocaleResolver localeResolver;

    public LoginController(OktaOAuth2Properties oktaOAuth2Properties, LocaleResolver localeResolver) {
        this.oktaOAuth2Properties = oktaOAuth2Properties;
        this.localeResolver = localeResolver;
    }

    @GetMapping(value = "/custom-login")
    public ModelAndView login(HttpServletRequest request,
                              @RequestParam(name = "state", required = false) String state)
                              throws MalformedURLException {

        ...
        mav.addObject(LANGUAGE, localeResolver.resolveLocale(request));

        return mav;
    }

    ...
}

然后修改custom-login / src / main / resources / templates / login.html并添加一个config.language读取该值的设置。

config.redirectUri = /*[[${redirectUri}]]*/ '{redirectUri}';
config.language = /*[[${language}]]*/ '{language}';

重新启动一切,转到http:// localhost:8080 /?lang = zh-CN,单击登录按钮,它现在应该以英语呈现。

Sign-In Widget in English

Add Internationalization Bundles for Thymeleaf

为了使更改区域设置更加有效,请创建一个messages.properties在src / main / resources,并为键指定英文翻译。

hello=Hello
welcome=Welcome home, {0}!

创建messages_es.properties在同一目录中,并提供翻译。

hello=Hola
welcome=¡Bienvenido a casa {0}!

打开src / main / resources / templates / home.html并改变<p>Hello!</p>到以下内容:

<p th:text="#{hello}">Hello!</p>

用户也通过身份验证时,请更改欢迎消息。 的{0}值将被传递给键名的参数替换。

<p th:text="#{welcome(${#authentication.name})}">Welcome home,
    <span th:text="${#authentication.name}">Joe Coder</span>!</p>

重新启动Spring Boot,登录,您应该在所选的语言环境中看到一条欢迎消息。

Home page in Spanish

您必须承认,这真是太棒了! 有件事告诉我,如果通过Okta中的用户属性设置区域设置,那就更好了。 让我们做到这一点!

Use the User’s Locale from Okta

要通过Okta中的用户信息设置语言环境,请创建一个OidcLocaleResolver类与MvcConfigurer。

package com.okta.spring.example;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;

import javax.servlet.http.HttpServletRequest;
import java.util.Locale;

@Configuration
public class OidcLocaleResolver extends CookieLocaleResolver {
    private final Logger logger = LoggerFactory.getLogger(OidcLocaleResolver.class);

    @Override
    public Locale resolveLocale(HttpServletRequest request) {
        SecurityContext securityContext = SecurityContextHolder.getContext();
        if (securityContext.getAuthentication().getPrincipal() instanceof OidcUser) {
            OidcUser user = (OidcUser) securityContext.getAuthentication().getPrincipal();
            logger.info("Setting locale from OidcUser: {}", user.getLocale());
            return Locale.forLanguageTag(user.getLocale());
        } else {
            return request.getLocale();
        }
    }
}

然后更新MvcConfigurer使用此类:

@Bean
public LocaleResolver localeResolver() {
   return new OidcLocaleResolver();
}

重新启动并导航至http:// localhost:8080 /?lang = es,并进行身份验证。 您应该使用英语(或用户所在的语言环境)作为语言回到您的应用首页。

Home page in English

耶eh! 感觉像星期五,不是吗? 😃

i18n in JavaScript with Angular, React, and Vue

在本文中,您了解了如何国际化基本Java程序和Spring Boot应用程序。 我们几乎没有涉及如何在JavaScript中执行i18n的服务。 好消息是我为JavaScript应用提供了一个出色的i18n示例。

ĴHipster is powered by Spring Boot and includes localization for many languages on the server and the client. It supports three awesome front-end frameworks: Angular, React, and Vue. It uses the following libraries to lazy-load JSON files with translations on the client. I invite you to check them out if you’re interested in doing i18n in JavaScript (or TypeScript).

Internationalize Your Java Apps Today!

I hope you’ve enjoyed this whirlwind tour of how to internationalize and localize your Java and Spring Boot applications. If you’d like to see the completed source code, you can find it on GitHub.

ŤIP: Baeldung’s Guide to Internationalization in Spring Boot was a useful resource when writing this post.

我们喜欢在此博客上撰写有关Java和Spring Boot的文章。 以下是一些我的最爱:

Follow us on your favorite social network { Twitter, LinkedIn, Facebook, YouTube } to be notified when we publish awesome content in the future.

from: https://dev.to//oktadev/i18n-in-java-11-spring-boot-and-javascript-37mo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值