Spring boot教程-RESTful 服务的国际化
RESTful 服务的国际化
在这一部分,我们将讨论 RESTful Web 服务的国际化。
国际化
国际化是这样一个过程:设计 Web 应用程序或服务以自动提供对各个国家和各种语言的支持,而无需对应用程序进行更改。国际化也称为 I18N,因为国际化一词的总长度为 18 个字符,从字母 "I" 到 "N"。
国际化通过添加特定于区域设置的组件(例如翻译后的文本、描述区域设置特定行为的数据等)来执行本地化。它支持完全集成到提供语言或文化相关功能的类和包中。
Java为桌面和服务器应用程序提供了国际化的基础。以下是功能的重要国际化领域:
- 文本表示: Java基于Unicode字符集,并且有几个库实现了Unicode标准。
- 区域设置识别和本地化: Java中的区域设置是可用于在不同功能领域中请求特定于区域设置的行为的标识符。本地化由ResourceBundle类支持。该类提供对特定区域设置的对象的访问,包括字符串。
- 日期和时间处理: Java提供了各种日历。它支持与独立于日历的日期对象之间的转换。Java支持世界上所有的时区。
- 文本处理: 它包括字符分析,大小写映射,字符串比较,将文本分解为单词,格式化数字、日期和时间值为字符串,或从字符串解析出它们。其中大多数功能都依赖于区域设置。
- 字符编码: 它支持在从流中读取传入文本或将传出文本写入流时,在Unicode和其他字符编码之间进行文本转换。
为了使服务国际化,我们需要配置两个东西:
- LocaleResolver(区域设置解析器)
- ResourceBundleMessageSource(资源束消息源)
默认区域设置为Locale.US(美国)。如果某人没有指定位置,它将返回默认区域设置。我们还需要自定义ResourceBundle。它有一个需要国际化的属性列表。我们将属性存储在ResourceBundle中。ResourceBundleMessageSource 是用于处理属性的Spring MVC概念。在那之后,我们将使用MessageSource和一个名为Accept-Language的标头。
让我们进行国际化配置。
Step 1: 打开 RestfulWebServicesApplication.java 文件。
Step 2: 为 default 区域设置一个 Bean。
@Bean
public LocaleResolver localeResolver()
{
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
localeResolver.setDefaultLocale(Locale.US);
return localeResolver;
}
注意:导入 LocaleResolver 时,请导入 import org.springframework.web.servlet.LocaleResolver 包。
Step 3: 现在,我们将属性存储在名为 messages.properties 的特定文件中。
右键单击 src/main/resources 文件夹 -> 新建 -> 文件 -> 输入文件名:messages.properties。它包含默认区域设置消息。
messages.properties
good.morning.message=Good Morning
Step 4: 创建名为 messages_fr.properties 的另一个属性文件,用于法语区域设置。它包含了法语区域设置的消息。
messages_fr.properties
good.morning.message=Bonjour
Step 5: 根据输入的 Accept Header 读取属性并进行定制。打开 RestfulWebServicesApplication.java 文件,为 ResourceBundle 配置另一个 Bean。
//configuring ResourceBundle
@Bean
public ResourceBundleMessageSource bundleMessageSource()
{
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
RestfulWebServicesApplication.java
package cn.javatiku.server.main;
import java.util.Locale;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
@SpringBootApplication
public class RestfulWebServicesApplication
{
public static void main(String[] args)
{
SpringApplication.run(RestfulWebServicesApplication.class, args);
}
//configuring default locale
@Bean
public LocaleResolver localeResolver()
{
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
localeResolver.setDefaultLocale(Locale.US);
return localeResolver;
}
//configuring ResourceBundle
@Bean
public ResourceBundleMessageSource messageSource()
{
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
}
步骤 6:更新服务以使用这些资源。打开 HelloWorldController.java 文件,并使用 @Autowired 注入 MessageSource。
@Autowired
private MessageSource messageSource;
HelloWorldController.java
package cn.javatiku.server.main.helloworld;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
import java.util.Locale;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Configuration;
@Configuration
//Controller
@RestController
public class HelloWorldController
{
@Autowired
private MessageSource messageSource;
//using get method and hello-world URI
@GetMapping(path="/hello-world")
public String helloWorld()
{
return "Hello World";
}
@GetMapping(path="/hello-world-bean")
//method- which returns "Hello World"
public HelloWorldBean helloWorldBean()
{
return new HelloWorldBean("Hello World");//constructor of HelloWorldBean
}
//passing a path variable
//hello-world/path-variable/javatiku
@GetMapping(path="/hello-world/path-variable/{name}")
public HelloWorldBean helloWorldPathVariable(@PathVariable String name)
{
return new HelloWorldBean(String.format("Hello World, %s",name)); //%s replace the name
}
//internationalization
@GetMapping(path="/hello-world-internationalized")
public String helloWorldInternationalized(@RequestHeader(name="Accept-Language", required=false) Locale locale)
{
return messageSource.getMessage("good.morning.message", null, locale);
}
}
Step7: 打开 REST 客户端 Postman 并执行以下更改:
- 选择 GET 请求。
- 输入 URI:http://localhost:8080/hello-world-internationalized
- 单击 Headers 标签,并输入:
- 单击发送按钮。
它返回了美国区域设置的消息 早上好。
现在,将请求标头从 fr 更改为其他值,例如 us。它会返回默认区域设置(美国)的消息 Good Morning。
让我们创建一个名为 message_nl.properties 的属性文件用于请求标头 nl。它包含荷兰语(Dutch)语言的消息 Goede Morgen。
messages_nl.properties
good.morning.message=Goede Morgen
再次发送 GET 请求,它会返回消息 Goede Morgen。
简化国际化
现在,我们将简化上述的国际化实现。在之前的实现中,我们在 REST 控制器方法中将区域设置(RequestHeader)作为参数。如果我们在每个需要进行国际化的方法中都添加这个参数,那么成本会增加。Spring 提供了一种替代方法,即从 LocaleContextHolder 获取它。
让我们实现 LocaleContextHolder 而不是 RequestHeader。
Step 1: 打开 HelloWorldController.java 文件,将 helloWorldInternationalized() 方法的返回类型更改为如下所示。
return messageSource.getMessage("good.morning.message", null, LocaleContextHolder.getLoca
HelloWorldController.java
package cn.javatiku.server.main.helloworld;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
import java.util.Locale;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.i18n.LocaleContextHolder;
@Configuration
//Controller
@RestController
public class HelloWorldController
{
@Autowired
private MessageSource messageSource;
//using get method and hello-world URI
@GetMapping(path="/hello-world")
public String helloWorld()
{
return "Hello World";
}
@GetMapping(path="/hello-world-bean")
//method- which returns "Hello World"
public HelloWorldBean helloWorldBean()
{
return new HelloWorldBean("Hello World");//constructor of HelloWorldBean
}
//passing a path variable
//hello-world/path-variable/javatiku
@GetMapping(path="/hello-world/path-variable/{name}")
public HelloWorldBean helloWorldPathVariable(@PathVariable String name)
{
return new HelloWorldBean(String.format("Hello World, %s",name)); //%s replace the name
}
//internationalization
@GetMapping(path="/hello-world-internationalized")
public String helloWorldInternationalized(@RequestHeader(name="Accept-Language", required=false) Locale locale)
{
return messageSource.getMessage("good.morning.message", null, LocaleContextHolder.getLocale());
}
}
Step 2: 打开 RestfulWebServicesApplication.java,将 SessionLocaleResolver 更改为 AcceptHeaderLocaleResolver。LocaleResolver 实现使用 HTTP 请求的 "accept-language" 标头中指定的主要区域设置(由客户端浏览器发送的区域设置)。
RestfulWebServicesApplication.java
package cn.javatiku.server.main;
import java.util.Locale;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
@SpringBootApplication
public class RestfulWebServicesApplication
{
public static void main(String[] args)
{
SpringApplication.run(RestfulWebServicesApplication.class, args);
}
//configuring default locale
@Bean
public LocaleResolver localeResolver()
{
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
localeResolver.setDefaultLocale(Locale.US);
return localeResolver;
}
//configuring ResourceBundle
@Bean
public ResourceBundleMessageSource messageSource()
{
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
}
AcceptHeaderLocaleResolver 的优势在于,我们不需要在每个控制器方法中配置请求标头作为参数。
Step 3: 打开 REST 客户端 Postman 并发送一个 GET 请求,将键设置为 Accept-Language,值设置为 fr。它会返回消息 Bonjour。
现在取消选中请求标头,将值 fr 更改为 en。它会返回默认区域设置(美国)的消息 Good Morning。
Step 4: 移至 RestfulWebServicesApplication.java。移除 ResourceBundleMessageSource() 方法,并将其配置在 application.properties 文件中。
Step 5: 打开 application.properties 文件,并配置消息基本名称,而不是在 RestfulWebServicesApplication.java 中创建单独的 bean。
application.properties
logging.level.org.springframework=info
spring.messages.basename=messages
Step 6: 重复第 3 步。