千家信息网

Springboot+AOP怎么实现返回数据提示语国际化

发表于:2024-11-15 作者:千家信息网编辑
千家信息网最后更新 2024年11月15日,本篇内容介绍了"Springboot+AOP怎么实现返回数据提示语国际化"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅
千家信息网最后更新 2024年11月15日Springboot+AOP怎么实现返回数据提示语国际化

本篇内容介绍了"Springboot+AOP怎么实现返回数据提示语国际化"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

正文

先看这次示例教学的项目 目录结构:

(当然resource里面的i18n文件夹和三个properties文件也是要我们自己建的,但是 那个Resource Bundle 不用管,这个在yml加上对应配置项自动生成的。 不清楚的继续往下看教学就好)

开始敲(CV)代码:

pom.xml 依赖:

                    org.springframework.boot            spring-boot-starter-web                            com.alibaba            fastjson            1.2.68                            org.apache.commons            commons-lang3            3.9                            org.projectlombok            lombok            1.18.10            provided                            org.springframework.boot            spring-boot-starter-aop                            org.springframework.boot            spring-boot-starter-test            test            

返回码的枚举

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 {    @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); }}

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 {     @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;    }}

接下来是我们转换的一个关键环节, 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 = "true")public class LanguageAspect {    @Autowired    I18nUtils 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;        }    }}

代码简单解读:

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文件:

mess.properties

自定义的返回语= 您好,如果文章对你有用,请关注+收藏+评论

这个文件按照本文里aop的拦截方式,会先检测 当前 的 语言flag值,如果检测不到就h会到
mess.properties 文件里面找。

mess_en_US.properties

请求成功=success
请求失败=fail

mess_zh_CN.properties

请求成功=请求成功
请求失败=请求失败
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怎么实现返回数据提示语国际化"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

0