springboot国际化

我爱海鲸 2023-11-14 12:53:38 暂无标签

简介springboot国际化、异常、exception

0、搭建springboot项目

1、首先在resources中添加各个国际化的配置包:

如图:

其中:en_US表示英文、zh_CN表示简体中文、zh_TW表示繁体中文

2、配置全局异常处理器:

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler { 

private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    private static final String HEADER_LANG = "Lang";

    /**
     * 英文
     */
    private static final String LANG_EN = "en";

    /**
     * 简体中文
     */
    private static final String LANG_ZH_CH = "zh_ch";

    /**
     * 繁体中文
     */
    private static final String LANG_ZH_TW = "zh_tw";

    /**
     * 权限校验异常
     */
    @ExceptionHandler(AccessDeniedException.class)
    public AjaxResult handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',权限校验失败'{}'", requestURI, e.getMessage());
        return AjaxResult.error(HttpStatus.FORBIDDEN, "没有权限,请联系管理员授权");
    }

    /**
     * 请求方式不支持
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e,
                                                          HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());
        return AjaxResult.error(e.getMessage());
    }

    /**
     * 业务异常
     */
    @ExceptionHandler(ServiceException.class)
    public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request) {
        String message = e.getMessage();
        Object[] objects = e.getObjects();
        return handleError(message,request,objects);
    }

    /**
     * 拦截未知的运行时异常
     */
    @ExceptionHandler(RuntimeException.class)
    public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',发生未知异常.", requestURI, e);
        return AjaxResult.error(e.getMessage());
    }

    /**
     * 系统异常
     */
    @ExceptionHandler(Exception.class)
    public AjaxResult handleException(Exception e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',发生系统异常.", requestURI, e);
        return AjaxResult.error(e.getMessage());
    }

    /**
     * 自定义验证异常
     */
    @ExceptionHandler(BindException.class)
    public AjaxResult handleBindException(BindException e) {
        log.error(e.getMessage(), e);
        String message = e.getAllErrors().get(0).getDefaultMessage();
        return AjaxResult.error(message);
    }

    /**
     * 自定义验证异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public AjaxResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e, HttpServletRequest request) {
        log.error(e.getMessage(), e);
        BindingResult bindingResult = e.getBindingResult();
        ObjectError objectError = bindingResult.getAllErrors().get(0);
        log.info("objName: {}, code: {}, codes: {}, obj: {}, objectError: {}", objectError.getObjectName(), objectError.getCode(), objectError.getDefaultMessage(), objectError.getCodes(), JSONUtil.toJsonStr(objectError));
        FieldError error = bindingResult.getFieldError();
        assert error != null;
        String errorDesc = error.getDefaultMessage();
        return handleError(errorDesc,request,null);
    }

    /**
     * 异常处理
     * @param errorDesc 异常信息
     * @param request 请求
     * @param objects 可变参数
     * @return ignore
     */
    private AjaxResult handleError(String errorDesc, HttpServletRequest request,Object[] objects) {
        try{
            // 默认为简体中文
            Locale locale = Locale.CHINA;
            // 国际化语言
            String headerLang = request.getHeader(HEADER_LANG);
            if (LANG_EN.equals(headerLang)) {
                // 英文
                locale = Locale.US;
            } else if (LANG_ZH_TW.equals(headerLang)) {
                // 繁体中文
                locale = Locale.TAIWAN;
            }
            if (objects != null && objects.length != 0) {
                errorDesc = MessageUtils.message(errorDesc,locale,objects);
            } else {
                errorDesc = MessageUtils.message(errorDesc,locale);
            }
        } catch (Exception ex){
            log.warn("BindException I18N error: {}", ex.toString());
        }
        return AjaxResult.error(errorDesc);
    }
MessageUtils:
public class MessageUtils {
    /**
     * 根据消息键和参数 获取消息 委托给spring messageSource
     *
     * @param code 消息键
     * @param args 参数
     * @return 获取国际化翻译值
     */
    public static String message(String code, Object... args) {
        MessageSource messageSource = SpringUtils.getBean(MessageSource.class);
        return messageSource.getMessage(code, args, LocaleContextHolder.getLocale());
    }

    /**
     * 根据消息键和参数 获取消息 委托给spring messageSource
     * @param code 消息键
     * @param locale 国际化参数
     * @param args 参数
     * @return 获取国际化翻译值
     */
    public static String message(String code, Locale locale, Object... args) {
        MessageSource messageSource = SpringUtils.getBean(MessageSource.class);
        return messageSource.getMessage(code, args, locale);
    }

    public static String message(String code, Locale locale) {
        return message(code,locale,null);
    }
}

3、创建一个自定义异常

public final class ServiceException extends RuntimeException {
    private static final long serialVersionUID = 1L;

    /**
     * 错误码
     */
    private Integer code;

    /**
     * 错误提示
     */
    private String message;

    /**
     * 空构造方法,避免反序列化问题
     */
    public ServiceException() {
    }

    public ServiceException(String message) {
        this.message = message;
    }

    public ServiceException(String message, Integer code) {
        this.message = message;
        this.code = code;
    }


    public String getMessage() {
        return message;
    }

    public Integer getCode() {
        return code;
    }

    public ServiceException setMessage(String message) {
        this.message = message;
        return this;
    }
}

4、在spring的配置文件中配置相关的资源路径,如:

# Spring配置
spring:
# 资源信息
messages:
# 国际化资源文件路径
basename: i18n/messages,i18n/messages_en_US,i18n/messages_zh_CN,i18n/messages_zh_TW
5、然后就可以在国际化资源配置文件中配置了,如图:


 

你好:我的2025