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

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

相关推荐
工业互联网专业1 小时前
基于springboot+vue的 嗨玩-旅游网站
java·vue.js·spring boot·毕业设计·源码·课程设计·旅游
码蜂窝编程官方1 小时前
【含开题报告+文档+PPT+源码】基于SpringBoot+Vue的医院挂号预约管理系统
java·vue.js·spring boot·后端·spring
綦枫Maple2 小时前
《跟我学Spring Boot开发》系列文章索引❤(2025.01.09更新)
java·spring boot·后端
superCleanCoder2 小时前
spring boot启动源码分析(三)之Environment准备
java·spring boot
小万编程3 小时前
【2025最新计算机毕业设计】基于SpringBoot+Vue奶茶点单系统(高质量源码,提供文档,免费部署到本地)
java·spring boot·计算机毕业设计·java毕业设计·web毕业设计
顽疲4 小时前
springboot vue uniapp 仿小红书 1:1 还原 (含源码演示)
vue.js·spring boot·uni-app
多多*4 小时前
后端技术选型 sa-token校验学习 上 登录校验复习
java·spring boot·后端
华如锦5 小时前
【JAVA架构】开发学校内部论文,文章查重系统【python】
java·开发语言·人工智能·spring boot·python·spring
潜洋7 小时前
Sprint Boot教程之五十八:动态启动/停止 Kafka 监听器
java·spring boot·kafka
城沐小巷7 小时前
基于Springboot+Vue的仓库管理系统
vue.js·spring boot·后端