目录
前言
代码
测试
前言
在项目中要面临后端返回给前端展示,而展示给别人的告警信息是需要面向不同的语言,比如展示中文还是英文等等。
这个时候就需要在返回的json中将告警信息根据选择的语言来返回不同的信息。
代码
首先新建一个spring boot工程,这里就不多赘述。
在工程中配置自己的国际化文件,XXX.properties,如下图所示,这里的Resource Bundle 'mess'是idea自动生成的,不用管,只需要建立i18n这个资源目录和下面三个properties文件。
第二步是在spring boot的配置文件中表名是读取哪些文件,如下图,此处是表名读取i18n目录下mess开头的文件。
# 是否开启国际化返回 #lang.open: false spring: messages: basename: i18n.mess
第三步是编写国际化文件读取类,I18nUtils和LocaleMessage类,代码如下,
package com.staryea.i18n;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Locale;
/**
* @author lw
* @date 2022/3/15 0015
* @description
*/
@Component
public class I18nUtils {
@Autowired
private LocaleMessage localeMessage;
/**
* 获取key
*
* @param key
* @return
*/
public String getKey(String key) {
String name = localeMessage.getMessage(key);
return name;
}
/**
* 获取指定哪个配置文件下的key
*
* @param key
* @param local
* @return
*/
public String getKey(String key, Locale local) {
String name = localeMessage.getMessage(key, local);
return name;
}
}
package com.staryea.i18n;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;
import java.util.Locale;
/**
* @author lw
* @date 2022/3/15 0015
* @description
*/
@Component
public class LocaleMessage {
@Autowired
private MessageSource messageSource;
public String getMessage(String code) {
return this.getMessage(code, new Object[]{});
}
public String getMessage(String code, String defaultMessage) {
return this.getMessage(code, null, defaultMessage);
}
public String getMessage(String code, String defaultMessage, Locale locale) {
return this.getMessage(code, null, defaultMessage, locale);
}
public String getMessage(String code, Locale locale) {
return this.getMessage(code, null, "", locale);
}
public String getMessage(String code, Object[] args) {
return this.getMessage(code, args, "");
}
public String getMessage(String code, Object[] args, Locale locale) {
return this.getMessage(code, args, "", locale);
}
public String getMessage(String code, Object[] args, String defaultMessage) {
return this.getMessage(code, args, defaultMessage, LocaleContextHolder.getLocale());
}
public String getMessage(String code, Object[] args, String defaultMessage, Locale locale) {
return messageSource.getMessage(code, args, defaultMessage, locale);
}
}
两个工具类写好后,下面就是编写AOP拦截,拦截返回的code,将msg赋值为国际化读取的信息。
此AOP拦截代码如下图所示,
package com.staryea.i18n;
import com.app.frame.util.PageData;
import com.staryea.app.version.VersionController;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
/**
* @author JCccc
*/
@Aspect
@Component
@ConditionalOnProperty(prefix = "lang", name = "open", havingValue = "true")
public class LanguageAspect {
private static final Log LOG = LogFactory.getLog(LanguageAspect.class);
@Autowired
I18nUtils i18nUtils;
@Pointcut("execution(public * com.staryea.app.*.*Controller.*(..))")
public void annotationLangCut() {
}
/**
* 拦截controller层返回的结果,修改msg字段
*
* @param point
* @param resultObject
*/
@AfterReturning(pointcut = "annotationLangCut()", returning = "resultObject")
public void around(JoinPoint point, PageData resultObject) {
try {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
//从获取RequestAttributes中获取HttpServletRequest的信息
HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
String langFlag = request.getHeader("dimLang");
if (null != langFlag) {
String msg = resultObject.getString("result_msg");
String code = resultObject.getString("result_code");
if (code!=null&&!"".equals(code)) {
code = code.trim();
Locale locale = null;
if ("zh-CN".equals(langFlag)) {
locale = Locale.CHINA;
} else if ("en-US".equals(langFlag)) {
locale = Locale.US;
}
if(locale!=null){
msg = i18nUtils.getKey(code, locale);
}else {
msg = i18nUtils.getKey(code);
}
}
resultObject.put("result_msg",msg);
}
} catch (Exception e) {
LOG.error(e);
}
}
}
其中,@ConditionalOnProperty是读取yml中配置的 lang.open的值,为true则AOP生效,否则不生效。
@ConditionalOnProperty(prefix = "lang", name = "open", havingValue = "true")
可以在yml中做如下配置,下面是开启国际化,
# 是否开启国际化返回 lang.open: true
测试
在mess_zh_CN.properties和mess.properties中写入如下内容,
0=成功
112=重复操作
113=工号有工牌
114=工牌有工号
在mess_en_US.properties中写入如下内容,
0=success
112=repeat oper
113=code has mac
114=mac has code
可以看到AOP拦截的是包名为 com.staryea.app下所有包下面的以Controller结尾的,所有的方法。
@Pointcut("execution(public * com.staryea.app.*.*Controller.*(..))")
那么就按照此写一个Controller,如下所示,
测试类如下,默认返回0.
@GetMapping("/testI18n")
public PageData testI18n(HttpServletRequest request){
return RespUtil.getSuccessResp();
}
然后在postman中调用地址进行测试,