博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringBoot系列之服务端解析客户端国际化请求
阅读量:5986 次
发布时间:2019-06-20

本文共 5482 字,大约阅读时间需要 18 分钟。

国际化方案

前后端分离的国际化方案,如果每个接口都增加参数,代码量和测试量会很大,最好把语言变量加到请求头并通过拦截器解析。

具体过程如下:

  1. 客户端增加请求头 Accept-Language;
  2. 服务端增加拦截器,解析请求头Accept-Language中的语言值,并通过LanguageUtil设置到当前线程的语言环境中;
  3. 服务端需要返回多语言结果的地方,通过LanguageUtil获取当前请求客户端的语言。

除了请求头,也可以通过cookie实现,但是有些客户端不支持cookie,而且cookie存在被篡改的危险,因此更建议使用标准的请求头。

实现代码

通过 SpringMVC 的RequestContextUtilsjava.util.Local,可以很轻松地解析请求头中的语言标识。

SpringMVC提供了多种国际化的实现方式。

下面一步步讲解代码实现。

pom.xml

使用SpringBoot搭建项目,并且引入Lombok用于简化JavaBean。

4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.3.RELEASE
net.ijiangtao.tech.framework.spring.ispringboot.demo
demo-i18n
0.0.1-SNAPSHOT
demo-i18n
Demo Spring Boot project for i18n
1.8
org.springframework.boot
spring-boot-starter-web
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
复制代码

application.properties

配置当前服务的端口。

server.port=8303复制代码

LanguageUtil.java

使用ThreadLocal保存当前线程的环境语言。

/** * @author ijiangtao.net */public class LanguageUtil {    public static final String ZH_CN = "zh_CN";    public static final String EN_US = "en_US";    public static final String DEFAULT_LANGUAGE = ZH_CN;    private String lang;    private static final ThreadLocal
context = new ThreadLocal
() { @Override protected LanguageUtil initialValue() { return new LanguageUtil(); } }; public LanguageUtil() { lang = DEFAULT_LANGUAGE; } public static LanguageUtil getCurrentContext() { return (LanguageUtil) context.get(); } public static String getCurrentLang() { return getCurrentContext().lang; } public static void setCurrentLang(String lang) { getCurrentContext().lang = lang; } public static void remove() { context.remove(); }}复制代码

LanguageInterceptor.java

实现HandlerInterceptor接口,拦截并解析请求头中的环境语言,并设置到LanguageUtil中。

import lombok.extern.slf4j.Slf4j;import net.ijiangtao.tech.framework.spring.ispringboot.demo.i18n.util.LanguageUtil;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.LocaleResolver;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.support.RequestContextUtils;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.util.Locale;@Slf4jpublic class LanguageInterceptor implements HandlerInterceptor {    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)            throws Exception {        log.info("preHandle:请求前调用");        //请求头 当前语言        // Accept-Language: zh-CN        // Accept-Language: en-US        LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);        Locale local= localeResolver.resolveLocale(request);        log.info("local={} , localDisplayName={}",local.toString(),local.getDisplayName());        LanguageUtil.setCurrentLang(local.toString());        log.info("LanguageUtil.getCurrentLang() = {}",LanguageUtil.getCurrentLang());        return true;    }    @Override    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,                           ModelAndView modelAndView) throws Exception {        log.info("postHandle:请求后调用");    }    @Override    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)            throws Exception {        log.info("afterCompletion:请求调用完成后回调方法,即在视图渲染完成后回调");    }}复制代码

InterceptorConfig.java

配置拦截器并使之生效。

import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;@Configurationpublic class InterceptorConfig extends WebMvcConfigurationSupport {    @Override    public void addInterceptors(InterceptorRegistry registry){        registry.addInterceptor(new LanguageInterceptor())                .addPathPatterns("/**")                .excludePathPatterns("/noi18n")                .excludePathPatterns("/onelang");    }}复制代码

LanguageController.java

从LanguageController中获取当前线程设置的环境语言,测试效果。

import net.ijiangtao.tech.framework.spring.ispringboot.demo.i18n.util.LanguageUtil;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.ResponseBody;/** * * @author ijiangtao.net */@Controllerpublic class LanguageController {    @GetMapping("/lang/current")    @ResponseBody    public String currentLanguage(){        return LanguageUtil.getCurrentLang();    }}复制代码

测试

使用IDEA的Rest Client发起请求

测试请求的response

en_US复制代码

总结

本教程介绍了如何通过客户端的请求头设置服务端的语言环境,从而实现服务端响应内容的国际化。

希望对你有所帮助。

Links

转载于:https://juejin.im/post/5c9b4412f265da610614903f

你可能感兴趣的文章
数据库权限设计
查看>>
.net 事件传递
查看>>
require和include区别
查看>>
新安装系统安装QQ不能使用
查看>>
react-navigation 导航栏使用
查看>>
vanish(squid) + HAProxy + nginx + memcached(redis)
查看>>
/etc/inittab文件详解
查看>>
一个较完整的SpringMVC工程的配置
查看>>
JavaScript实现前端路由
查看>>
maven 搭建
查看>>
极速开发,快就是这么任性,你不知道的Jfinal2.0新特性
查看>>
Linux Notes
查看>>
iSCSI安装以及配置
查看>>
It is indirectly referenced from required .class file
查看>>
jenkins 自动化集成测试配置(一)
查看>>
进程和线程之间的关系.
查看>>
总结CString、string、char*
查看>>
设置listview,隔行不同style
查看>>
【eoe Android特刊】第二十五期 Android 应用的终端适配
查看>>
Java菜鸟零基础自学入门必备视频教程
查看>>