SpringBoot错误码国际化

先看测试效果:

文件结构

1.中文和英文的错误消息配置

java 复制代码
package com.ldj.mybatisflex.common;

import lombok.Getter;

/**
 * User: ldj
 * Date: 2025/1/12
 * Time: 17:50
 * Description: 异常消息枚举
 */
@Getter
public enum ExceptionEnum {
    
    //# code命名规则:模块编码 + 唯一序号 11表示用户管理模块

    LOGIN_EXCEPTION(1101),
    OTHER_EXCEPTION(1102);

    private Integer code;

    ExceptionEnum(Integer code) {
        this.code = code;
    }
}

2.统一响应类

java 复制代码
package com.ldj.mybatisflex.common;

import lombok.Getter;
import lombok.Setter;
import org.springframework.context.i18n.LocaleContextHolder;

import java.util.ResourceBundle;

/**
 * User: ldj
 * Date: 2025/1/12
 * Time: 18:08
 * Description: 统一响应类
 */
@Getter
@Setter
public class Response<T> {

    private static final String basePath = "i18n/message";

    private static final Integer successCode = 200;
    private static final String success = "成功!";

    private static final Integer failCode = 500;
    private static final String fail = "失败!";

    private Integer code;

    private String message;

    private T data;

    public static <T>Response<T> success(T data) {
        Response<T> response = new Response<>();
        response.setCode(200);
        response.setMessage(success);
        response.setData(data);
        return response;
    }

    public static <T>Response<T> fail() {
        return fail(failCode, fail);
    }


    //关键代码是读取国际化的配置文件,作为错误提示消息
    public static <T>Response<T> fail(ExceptionEnum exceptionEnum, T date) {
        Response<T> response = new Response<>();
        response.setCode(exceptionEnum.getCode());
        ResourceBundle bundle = ResourceBundle.getBundle(basePath, LocaleContextHolder.getLocale());
        String message = bundle.getString(exceptionEnum.getCode().toString());
        response.setMessage(message);
        response.setData(date);
        return response;
    }

    public static <T>Response<T> fail(Integer code, String message) {
        Response<T> response = new Response<>();
        response.setCode(code);
        response.setMessage(message);
        response.setData(null);
        return response;
    }
}

3.登录拦截器

java 复制代码
package com.ldj.mybatisflex.interceptor;

import org.springframework.context.i18n.LocaleContext;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.i18n.SimpleLocaleContext;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;

/**
 * User: ldj
 * Date: 2025/1/12
 * Time: 21:05
 * Description: 登录拦截器
 */
@Order(1)
@Component
public class LoginUserInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //需要前端传过来的,这里一直是null
        String language = request.getHeader("language");
        //假设前端传"en_US"
        //language = "en_US";

        //默认是zh_CN
        if (language == null || "".equals(language) || "zh_CN".equalsIgnoreCase(language)) {
            LocaleContext localeContext = new SimpleLocaleContext(Locale.SIMPLIFIED_CHINESE);
            LocaleContextHolder.setLocaleContext(localeContext);
        }else {
            LocaleContext localeContext = new SimpleLocaleContext(Locale.US);
            LocaleContextHolder.setLocaleContext(localeContext);
        }

        System.out.println("配置语言:" + LocaleContextHolder.getLocale());
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //请求结束后记得清理 ThreadLocal里面的值,好让垃圾回收器回收
        LocaleContextHolder.resetLocaleContext();
    }
}

4.配置webmvc 应用登录拦截器

java 复制代码
package com.ldj.mybatisflex.config;

import com.ldj.mybatisflex.interceptor.LoginUserInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * User: ldj
 * Date: 2025/1/12
 * Time: 21:00
 * Description: No Description
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private LoginUserInterceptor loginUserInterceptor;

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

5.测试

java 复制代码
package com.ldj.mybatisflex.controller;

import com.ldj.mybatisflex.common.ExceptionEnum;
import com.ldj.mybatisflex.common.Response;
import com.ldj.mybatisflex.model.dao.UerInfoDAO;
import com.ldj.mybatisflex.model.dto.UserLoginReqDTO;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

/**
 * User: ldj
 * Date: 2024/11/17
 * Time: 16:55
 * Description: No Description
 */
@RestController
@RequestMapping("/userInfo")
@CrossOrigin(maxAge = 3600)
public class UserInfoController {
    
    @PostMapping(value = "/login")
    public Response<UerInfoDAO> login(@RequestBody @Valid UserLoginReqDTO userLoginReqDTO){
        return Response.fail(ExceptionEnum.LOGIN_EXCEPTION, null);
    }
}

总结,这有个问题,每次读取配置文件都要操作io流,性能比直接定义在枚举差,3个字段,一个code ,1个cnMsg ,1个enMsg,再写个方法判断是否中,英获取消息。

但是如果是法语,就失去灵活性,要改代码

相关推荐
code_slave(码畜)11 小时前
微服务架构落地:基础服务 —— 报表服务(中篇:元数据、查询引擎、缓存与权限落地)
spring boot·spring cloud·缓存·微服务·架构
ZealSinger12 小时前
Boot4挂起函数丢traceId怎么修
spring boot·kotlin·协程·可观测性
code_slave(码畜)12 小时前
微服务架构落地:基础服务 —— 报表服务(AI 集成篇:AI 增强报表能力)
人工智能·spring boot·spring cloud·微服务·架构
code_slave(码畜)13 小时前
微服务架构落地:公共中间件层总览——不承载业务,只承载稳定性
spring boot·spring cloud·微服务·中间件·架构
谢亮_vipxieliang14 小时前
Spring Boot 自动配置原理:从 @SpringBootApplication 到自定义 Starter
java·spring boot·后端
AI人工智能+电脑小能手16 小时前
Java 企业级工具类全家桶-68-HTTP请求工具类
spring boot·网络请求·http请求·resttemplate·jdk 17·java工具类·企业级开发
paopaokaka_luck18 小时前
非遗文物数字化小程序(AI非遗问答、ONNX图像识别、协同过滤推荐、ECharts数据分析、非遗知识浏览与互动、文创商城订单闭环、文化活动报名签到、社区交流)
javascript·spring boot·mysql·数据分析·echarts·mybatis
EatFan20 小时前
Spring Boot 4 迁移避坑清单:Jackson 3、starter 拆分与最低 JDK 口径核对(含若依/芋道/CRMEB 升级对照)
java·数据库·spring boot·spring boot 4·java 21·jakarta ee 11·jackson 3
ly768920 小时前
Spring Boot 集成 Redis 企业级实践:连接池、序列化与缓存穿透雪崩的工程化防御
spring boot·redis·缓存·缓存穿透·布隆过滤器·lettuce 连接池
Wx-bishekaifayuan21 小时前
springboot陨石鉴收系统96265-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·python·spring·课程设计