0

0

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

WBOY

WBOY

发布时间:2023-05-29 15:45:33

|

1403人浏览过

|

来源于亿速云

转载

正文  

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

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
 */
@Data
public 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
 */
@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); }
}

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

接下来是我们转换的一个关键环节, 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怎么实现返回数据提示语国际化

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

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

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

805

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

724

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

727

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

395

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

398

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

445

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

428

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16861

2023.08.03

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Redis6入门到精通超详细教程
Redis6入门到精通超详细教程

共47课时 | 5.1万人学习

成为PHP架构师-自制PHP框架
成为PHP架构师-自制PHP框架

共28课时 | 2.4万人学习

YMP在线手册
YMP在线手册

共64课时 | 33万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号