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

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

相关推荐
张涛酱10745614 分钟前
Jackson 严格解析:拒绝"温柔"的 JSON
spring boot·json
Lyyaoo.36 分钟前
Spring,Spring MVC, Spring Boot
spring boot·spring·mvc
zhangren0246839 分钟前
Laravel8.x核心特性全解析
vue.js·spring boot·mysql
Java源码jdk42 分钟前
基于javaweb和mysql的springboot校园二手书交易管理系统(java+springboot+vue+elementui+layui+mysql)
java·spring boot·mysql
sheji34161 小时前
【开题答辩全过程】以 校园帮系统为例,包含答辩的问题和答案
java·spring boot
摇滚侠1 小时前
SpringBoot yml 配置文件,读取 Windows 系统环境变量
windows·spring boot·后端
希望永不加班2 小时前
SpringBoot 跨域问题(CORS)彻底解决方案
java·spring boot·后端·spring
小江的记录本2 小时前
【端口号】计算机领域常见端口号汇总(完整版)
java·前端·windows·spring boot·后端·sql·spring
indexsunny11 小时前
互联网大厂Java求职面试实战:微服务与Spring生态全攻略
java·数据库·spring boot·安全·微服务·面试·消息队列