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,再写个方法判断是否中,英获取消息。

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

相关推荐
砍材农夫9 小时前
spring-ai|Spring‑AI 2.0.0 新特性 + 入门教程
spring boot·spring·spring cloud
小强库计算机毕业设计12 小时前
SpringBoot+Vue3 学生宿舍管理系统实战
java·spring boot·后端·vue·学生宿舍管理系统
不是光头 强21 小时前
SpringBoot事务优化与状态机实战
java·spring boot·后端
Flittly2 天前
【雕虫大技】Agent 动态 Skill 供应链安全加固(三):输出校验与治理闭环实战
java·spring boot·spring
小强库计算机毕业设计2 天前
基于 Spring Boot + Vue3 的校园管理系统
java·spring boot·后端·项目实战·管理系统·技术分享·校园管理系统实战
毕设单片机2 天前
顺顺救助站流浪动物领养系统的设计与实现46649----SpringBoot + Vue.js + MySQL|领养审核、寻宠发布、救助站点与动物论坛协同
java·spring boot·管理系统·流浪动物
云烟成雨TD2 天前
Micrometer 系列【63】统一观测:基于 Spring Boot 的生产级演示案例 | 基于 OTLP 集成 Prometheus + Jaeger
spring boot·云原生·prometheus
csdn2015_2 天前
springboot +mybatis 查询myql开启程序级别缓存
spring boot·缓存·mybatis
chuan.bai2 天前
Java RAG 实战(第 8 篇):Spring Boot RAG 查询 API
java·spring boot·贪心算法
vx-程序开发2 天前
springboot旅游推介平台---附源码24175
java·spring boot·python·spring cloud·eclipse·django·idea