SpringBoot 返回值 i18n 自动处理

news2024/11/19 10:24:44

定义基础通用类
[图片]

首先定义一波错误码:ResultCode

@Getter
@AllArgsConstructor
public enum ResultCode {
    SUCCESS(200, "请求成功", "request.success"),
    Fail(400, "请求失败", "request.failed"),

    PASSWORD_NOT_MATCH(100000, "密码不匹配", "password.not.match"),

    ......

    ;

    private final Integer code; // 错误码code
    private final String desc; // 错误码描述
    private final String i18nKey; // 国际化字符串

    ResultCode(Integer code, String desc) {
        this.code = code;
        this.desc = desc;
        this.i18nKey = "";
    }
    
    }

定义返回对象:Result

@Getter
@Setter
public class Result<T> {
    private Integer code;
    private String message;
    private T data;

    public Result(Integer code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    public Result() {

    }

    /**
     * 成功返回
     *
     * @param data
     * @param <T>
     * @return
     */
    public static <T> Result<T> success(T data) {
        return new Result<>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getDesc(), data);
    }

    /**
     * 失败返回
     *
     * @param message
     * @return
     */
    public static Result<Object> failed(String message) {
        return new Result<>(ResultCode.Fail.getCode(), message, null);
    }

    /**
     * @param code
     * @param message
     * @return
     */
    public static Result<Object> failed(Integer code, String message) {
        return new Result<>(code, message, null);
    }

    /**
     * @param code
     * @return
     */
    public static Result<Object> failed(ResultCode code) {
        return new Result<>(code.getCode(), code.getDesc(), null);
    }
}

定义一个异常通用类:ApiException

@Getter
@Setter
public class ApiException extends RuntimeException {
    private static final long serialVersionUID = -8412830185919566727L;

    private Integer resultCode = ResultCode.UNKNOWN_CODE.getCode();
    private String I18nKey = "";

    public ApiException(String message) {
        super(message);
    }

    public ApiException(Integer resultCode, String message) {
        this(message);
        this.resultCode = resultCode;
    }

    public ApiException(Integer resultCode) {
        this(ResultCode.Fail.getDesc());
        this.resultCode = resultCode;
    }

    public ApiException(Throwable cause) {
        super(cause);
    }

    //支持传入code对象触发i18n数据
    public ApiException(ResultCode code) {
        this(code.getDesc());
        this.resultCode = code.getCode();
        this.I18nKey = code.getI18nKey();
    }
}

定义异常拦截器:ApiExceptionHandler

/**
 * 全局异常处理类
 * 指定拦截异常的类型,被捕获的异常会调用handler方法,方法名自己随便定
 *
 **/
@RestControllerAdvice
public class ApiExceptionHandler {
    /**
     * ApiException异常处理
     *
     * @param e 异常
     * @return 返回给前端的结果
     */
    @ExceptionHandler(value = ApiException.class)
    public Result<Object> apiExceptionHandler(ApiException e) {
        String message = "";
        String i18nKey = e.getI18nKey();
        
        String i18nMessage = i18nUtils.getMessage(i18nKey);
        if(i18nMessage.isEmpty()){
            message = i18nKey;
        }else{
            message = i18nMessage;
        }
        
        if(!message.isEmpty()){
            return Result.failed(e.getResultCode(), message);
        }
        
        return Result.failed(e.getResultCode(), e.getMessage());
    }
}

定义 i18n 配置类:I18nConfig

@Slf4j
@Configuration
public class I18nConfig implements WebMvcConfigurer {
    public static final String COOKIE_NAME = "locale";

    @Resource
    WebProperties webProperties;

    @Bean(name = "messageSource")
    public ResourceBundleMessageSource getMessageSource() throws Exception {
        ResourceBundleMessageSource resourceBundleMessageSource = new ResourceBundleMessageSource();
        resourceBundleMessageSource.setDefaultEncoding("UTF-8");
        resourceBundleMessageSource.setBasenames("i18n/messages");
        resourceBundleMessageSource.setCacheSeconds(3);
        return resourceBundleMessageSource;
    }

    /**
     * @return SessionLocaleResolver
     */
    @Bean
    public LocaleResolver localeResolver() {
        SessionLocaleResolver localeResolver = new SessionLocaleResolver();
        localeResolver.setDefaultLocale(getDefaultLocale());
        return localeResolver;
    }

    /**
     * Cookie方式
     */
    @Bean
    public LocaleResolver localeResolver2() {
        CookieLocaleResolver clr = new CookieLocaleResolver();
        clr.setCookieName(COOKIE_NAME);
        //设置默认区域
        clr.setDefaultLocale(getDefaultLocale());
        //设置cookie有效期.
        clr.setCookieMaxAge(3600);
        return clr;
    }

    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
        //对请求页面路径中的参数lang进行拦截
        lci.setParamName("lang");
        return lci;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(localeChangeInterceptor());
    }

    private Locale getDefaultLocale() {
        Locale locale = webProperties.getLocale();
        if (locale == null) {
            locale = Locale.SIMPLIFIED_CHINESE;
        }
        return locale;
    }

}

定义 i18n 消息内容处理器:I18nUtils

@Slf4j
@Component
public class I18nUtils {
    @Resource
    private MessageSource messageSource;

    /**
     * @param key:对应文本配置的key.
     * @return 对应地区的语言消息字符串
     */
    public String getMessage(String key) {
        return this.getMessage(key, new Object[]{});
    }

    public String getMessage(String key, String defaultMessage) {
        return this.getMessage(key, null, defaultMessage);
    }

    public String getMessage(String key, String defaultMessage, Locale locale) {
        return this.getMessage(key, null, defaultMessage, locale);
    }

    public String getMessage(String key, Locale locale) {
        return this.getMessage(key, null, "", locale);
    }

    public String getMessage(String key, Object[] args) {
        return this.getMessage(key, args, "");
    }

    public String getMessage(String key, Object[] args, Locale locale) {
        return this.getMessage(key, args, "", locale);
    }

    public String getMessage(String key, Object[] args, String defaultMessage) {
        Locale locale = LocaleContextHolder.getLocale();
        String message = this.getMessage(key, args, defaultMessage, locale);
        return message;
    }

    public String getMessage(String key, Object[] args, String defaultMessage, Locale locale) {
        return messageSource.getMessage(key, args, defaultMessage, locale);
    }

}

项目集成

编写i18n翻译文件

resources/i18n/messages.properties
password.not.match=密码不匹配

resources/i18n/messages_zh_CN.properties
password.not.match=密码不匹配

resources/i18n/messages_en_US.properties
password.not.match=The password does not match

接口处理层抛出异常

if (dateList.isEmpty()) {
    throw new ApiException(ResultCode.PASSWORD_NOT_MATCH);
}

数据返回
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1707689.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

保护“第二生命线”,科技守护颈椎健康

脊柱支撑着人体重量&#xff0c;汇集着众多血管神经&#xff0c;素有“人体第二生命线”之称。在如今快节奏的时代&#xff0c;人们生活方式也在发生着变化&#xff0c;长期低头看手机、伏案久坐等不良生活习惯引发脊柱健康问题&#xff0c;且呈现年轻化趋势。目前&#xff0c;…

2024.05.22学习记录

1、面经复习&#xff1a; Vue组件通讯、vuex、js严格模式、options请求、vue3 Setup 语法糖、React hook 2、代码随想录刷题&#xff1a;动态规划 3、rosebush组件库 完成Alert和Alert测试 Menu组件初步开发

基于单片机的自行车里程监测系统的设计

摘 要 &#xff1a;本设计是一种基于单片机的自行车里程监测系统&#xff0c;采用 STC89C52RC 单片机为核心处理芯片&#xff0c;液晶显示器使用 LCD1602 &#xff0c; 速度测量使用霍尔传感器&#xff0c;温度传感器使用 DS18B20 &#xff0c;时间由时钟芯片 DS1302 进行…

昆仑通态触摸屏组态软件MCGS 嵌入版V7.7.1.7老版触摸屏安装程序

1.MCGS7.7嵌入版用于昆仑通态老版本触摸屏组态开发&#xff0c;具体支持哪些型号组态&#xff0c;可以在软件的工程设置里面查看。新出的触摸屏一般用MCGS Pro版本组态开发&#xff0c;老版本触摸屏必须用MCGS 7.7嵌入版组态开发。 2.MCGS7.7嵌入版支持当下常用的Win7、Win10、…

Nodejs 第七十三章(网关层)

什么是网关层(getway)&#xff1f; 技术选型fastify 速度快适合网关层 fastify教程上一章有讲 网关层是位于客户端和后端服务之间的中间层&#xff0c;用于处理和转发请求。它充当了请求的入口点&#xff0c;并负责将请求路由到适当的后端服务&#xff0c;并将后端服务的响应…

怎样打造一份个性化画册呢?我来教你

在这个数字化的时代&#xff0c;传统的照片已经不能满足我们对个性化回忆的需求。个性化画册&#xff0c;不仅能够承载我们的记忆&#xff0c;还能展现自我风格。今天&#xff0c;就让我来教你如何打造一份属于自己的个性化画册。 1.要制作电子杂志,首先需要选择一款适合自己的…

Debian12 安装留档@Virtual Box

在学蜜罐系统的时候&#xff0c;T-Pot 需要Debian&#xff0c;于是安装Debian12 下载安装光盘 先去中科大下载了12的安装光盘&#xff0c;然后在VirtualBox中创建一个新虚拟机&#xff0c;将安装光盘挂载上。 安装光盘下载地址&#xff1a;https://mirrors.ustc.edu.cn/debi…

隐藏服务器源IP怎么操作,看这一篇学会!

在当今的网络环境中&#xff0c;服务器作为信息和服务的中枢&#xff0c;常驻于公网之上&#xff0c;面临着各式各样的安全威胁&#xff0c;其中&#xff0c;分布式拒绝服务&#xff08;DDoS&#xff09;攻击尤为猖獗&#xff0c;它通过协调大量计算机同时向目标服务器发送请求…

看花眼,眼花缭乱的主食冻干到底应该怎么选?靠谱的主食冻干分享

随着科学养猫知识的普及&#xff0c;主食冻干喂养越来越受到养猫人的青睐。主食冻干不仅符合猫咪的饮食天性&#xff0c;还能提供均衡的营养&#xff0c;有助于维护猫咪的口腔和消化系统健康。许多猫主人认识到了主食冻干喂养的诸多益处&#xff0c;计划尝试这种喂养方式&#…

缓存三问与缓存预热-如何预防缓存崩溃

一、缓存三剑客 &#xff08;图片来源&#xff1a;什么是缓存雪崩、击穿、穿透&#xff1f; | 小林coding&#xff09; 缓存穿透 (Cache Penetration) 又称"空缓存"指用户请求的数据在缓存和数据库中都不存在,导致每次请求都去查询数据库,给数据库带来巨大压力。解…

代码随想录——平衡二叉树(Leetcode110)

题目链接 后序遍历高度&#xff0c;高度判断是否平衡 前序遍历深度 递归 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* …

短视频再度重逢:四川京之华锦信息技术公司

短视频再度重逢 在数字化时代的浪潮中&#xff0c;短视频以其独特的魅力迅速崛起&#xff0c;成为现代人生活中不可或缺的一部分。而当我们谈论起短视频&#xff0c;我们不仅仅是在谈论一种娱乐方式&#xff0c;更是在谈论一种情感的载体&#xff0c;一种回忆的媒介。今天&…

143.栈和队列:用队列实现栈(力扣)

题目描述 代码解决 class MyStack { public:queue<int> que; // 定义一个队列用于实现栈// 构造函数&#xff0c;初始化队列MyStack() {}// 向栈中推入元素 xvoid push(int x) {que.push(x); // 使用队列的 push 方法将元素 x 添加到队列尾部}// 从栈中弹出并返回栈顶元…

【edge浏览器】控制台报错信息隐藏-恢复

问题描述 解决方法&#xff1a;只需要清空筛选器

软件构造复习1

一、软件构造的多维度视图&#xff1a; 共有三个维度&#xff1a;1.按阶段划分&#xff1a;构造时/运行时视图&#xff0c;2.按动态性划分&#xff1a;时刻/阶段视图&#xff0c;3.按构造对象层次划分&#xff1a;代码/构件视图 具体可如图所示&#xff08;图片来自PPT&#…

Vue3实战笔记(36)—粒子特效完成炫酷的404

文章目录 前言404特效总结 前言 昨天介绍了一个粒子特效小例子&#xff0c;不够直观&#xff0c;下面直接实战在自己的项目中实现一个好玩滴。 404特效 更改之前创建好的404.vue: <template><div class"container"><vue-particles id"tspartic…

怎么做图片海报二维码?扫码查看图片内容

现在很多的宣传推广海报会放入二维码中&#xff0c;然后将二维码分享给用户后&#xff0c;通过扫码的方式来查看图片内容&#xff0c;从而获取自己需要的信息&#xff0c;经常在活动宣传、商品推广、旅游攻略等场景下使用。二维码可以提供更加便捷的内容获取方式&#xff0c;让…

Go源码--sync库(1)

简介 这篇主要介绍 sync.Once、sync.WaitGroup和sync.Mutex sync.Once once 顾名思义 只执行一次 废话不说 我们看源码 英文介绍直接略过了 感兴趣的建议读一读 获益匪浅 其结构体如下 Once 是一个严格只执行一次的object type Once struct {// 建议看下源码的注解&#xf…

llama_factory的使用

1.git clone llama_factory到本地 2.记得安环境&#xff0c;在clone后 3.多显卡要设置一下 4.数据文件放在data里面&#xff0c;仿照模板里的格式 5.进入llama_factory微调页面 python src/webui.py 6.llama_factory介绍&#xff1a;10分钟打造你个人专属的语言大模型&am…

「Element-UI表头添加带Icon的提示信息」

一、封装全局组件 &#x1f353; 注意&#xff1a;可以直接复制该文件 <!-- // 写一个PromptMessage的组件&#xff0c;并全局注册 --> <template><div class"tooltip"><el-tooltip effect"dark" placement"right">&l…