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、然后就可以在国际化资源配置文件中配置了,如图: