Springboot+AOP实现返回数据提示语国际化的示例代码
前言
本篇内容:
提示语的国际化返回,自定义多语言。
本文使用aop方式,拦截接口返回的数据,进行转换。
正文
先看这次示例教学的项目 目录结构:
【Springboot+AOP实现返回数据提示语国际化的示例代码】
文章图片
(当然resource里面的i18n文件夹和三个properties文件也是要我们自己建的,但是 那个Resource Bundle 不用管,这个在yml加上对应配置项自动生成的。 不清楚的继续往下看教学就好)
开始敲(CV)代码:
pom.xml 依赖:
org.springframework.boot spring-boot-starter-webcom.alibaba fastjson1.2.68 org.apache.commons commons-lang33.9 org.projectlombok lombok1.18.10 providedorg.springframework.boot spring-boot-starter-aoporg.springframework.boot spring-boot-starter-testtest
返回码的枚举CodeEnum.java
/** * @author JCccc */public enum CodeEnum { SUCCESS(1000, "请求成功"),FAIL(2000, "请求失败"); public final int code; public final String msg; public Integer getCode() {return this.code; }CodeEnum(int code, String msg) {this.code = code; this.msg = msg; }public String getMsg() {return this.msg; }}
返回数据的简单封装ResultData.java
import com.test.myi18n.enums.CodeEnum; import lombok.Data; /** * @author JCccc */@Datapublic class ResultData{private Integer code; private String message; private T data; public ResultData(int code, String message) {this.code = code; this.message = message; }public static ResultData success(CodeEnum codeEnum) {return new ResultData(codeEnum.code, codeEnum.msg); }public static ResultData success(String msg) {return new ResultData(CodeEnum.SUCCESS.getCode(),msg); }}
Locale、 MessageSource的简单方法封装LocaleMessage.java
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 JCccc */@Componentpublic class LocaleMessage {@Autowiredprivate 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); }}
i18n语言转换工具类I18nUtils.java
import java.util.Locale; import com.test.myi18n.message.LocaleMessage; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Componentpublic class I18nUtils { @Autowiredprivate LocaleMessage localeMessage; /*** 获取key** @param key* @return*/publicString getKey(String key) {String name = localeMessage.getMessage(key); return name; } /*** 获取指定哪个配置文件下的key** @param key* @param local* @return*/publicString getKey(String key, Locale local) {String name = localeMessage.getMessage(key, local); return name; }}
接下来是我们转换的一个关键环节, aop方式拦截 controller接口返回的数据:
LanguageAspect.java
import lombok.AllArgsConstructor; import org.apache.commons.lang3.StringUtils; 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@AllArgsConstructor@ConditionalOnProperty(prefix = "lang", name = "open", havingValue = "https://www.it610.com/article/true")public class LanguageAspect {@AutowiredI18nUtils i18nUtils; @Pointcut("execution(* com.test.myi18n.controller.*.*(..)))")public void annotationLangCut() {} /*** 拦截controller层返回的结果,修改msg字段** @param point* @param obj*/@AfterReturning(pointcut = "annotationLangCut()", returning = "obj")public void around(JoinPoint point, Object obj) {Object resultObject = obj; try {RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); //从获取RequestAttributes中获取HttpServletRequest的信息HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST); String langFlag = request.getHeader("lang"); if (null != langFlag) {ResultData r = (ResultData) obj; String msg = r.getMessage().trim(); if (StringUtils.isNotEmpty(msg)) {if ("CN".equals(langFlag)) {Locale locale = Locale.CHINA; msg = i18nUtils.getKey(msg, locale); } else if ("EN".equals(langFlag)) {Locale locale = Locale.US; msg = i18nUtils.getKey(msg, locale); } else {msg = i18nUtils.getKey(msg); }}r.setMessage(msg); }} catch (Exception e) {e.printStackTrace(); //返回原值obj = resultObject; }}}
代码简单解读:最后是 三份 mess properties文件:
1.annotationLangCut 上面切点管控的地址 需要自己改下,改成自己想管控的文件夹路径
2.@ConditionalOnProperty 注解,读取yml 里面lang开头的配置项,key为 open ,value 为true
只有为true,这个aop拦截才会生效
3.String langFlag = request.getHeader("lang");
从这句可以看到我这次文章采取的是让对接接口方(前端)在header里面传入需要使用的语言flag。 例如传入 EN (英文),意思就是需要把提示语转为英文。
大家可以结合自己的项目实际情况,改为从yml读取或者从数据库读取或者从redis读取等等都可以。
4.ResultData r = (ResultData) obj;
String msg = r.getMessage().trim();
这两行代码为了就是把拦截到的obj中的message提示语获取出来, 如果大家项目的返回数据不是我文中使用的 ResultData,则需要自己进行魔改调整。
mess.properties
自定义的返回语= 您好,如果文章对你有用,请关注+收藏+评论这个文件按照本文里aop的拦截方式,会先检测 当前 的 语言flag值,如果检测不到就h会到
mess.properties 文件里面找。
mess_en_US.properties
请求成功=successmess_zh_CN.properties
请求失败=fail
请求成功=请求成功最后写个测试接口给大家演示一下效果:
请求失败=请求失败
success=请求成功
fail=请求失败
@GetMapping("test")public ResultData test(@RequestParam int testNum) {if (1==testNum){return ResultData.success(CodeEnum.SUCCESS); }if (2==testNum){return ResultData.success(CodeEnum.FAIL); }if (3==testNum){return ResultData.success("自定义的返回语"); }return ResultData.success(CodeEnum.SUCCESS); }
调用测试:
文章图片
文章图片
文章图片
好,就先到这。
到此这篇关于Springboot+AOP实现返回数据提示语国际化的示例代码的文章就介绍到这了,更多相关Springboot 返回数据提示语内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- MybatisPlus使用queryWrapper如何实现复杂查询
- python学习之|python学习之 实现QQ自动发送消息
- 孩子不是实现父母欲望的工具——林哈夫
- opencv|opencv C++模板匹配的简单实现
- Node.js中readline模块实现终端输入
- java中如何实现重建二叉树
- 人脸识别|【人脸识别系列】| 实现自动化妆
- paddle|动手从头实现LSTM
- pytorch|使用pytorch从头实现多层LSTM