定义基础通用类
首先定义一波错误码:ResultCode
@Getter
@AllArgsConstructor
public enum ResultCode {
SUCCESS(200, "请求成功", "request.success"),
Fail(400, "请求失败", "request.failed"),
PASSWORD_NOT_MATCH(100000, "密码不匹配", "password.not.match"),
......
;
private final Integer code; // 错误码code
private final String desc; // 错误码描述
private final String i18nKey; // 国际化字符串
ResultCode(Integer code, String desc) {
this.code = code;
this.desc = desc;
this.i18nKey = "";
}
}
定义返回对象:Result
@Getter
@Setter
public class Result<T> {
private Integer code;
private String message;
private T data;
public Result(Integer code, String message, T data) {
this.code = code;
this.message = message;
this.data = data;
}
public Result() {
}
/**
* 成功返回
*
* @param data
* @param <T>
* @return
*/
public static <T> Result<T> success(T data) {
return new Result<>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getDesc(), data);
}
/**
* 失败返回
*
* @param message
* @return
*/
public static Result<Object> failed(String message) {
return new Result<>(ResultCode.Fail.getCode(), message, null);
}
/**
* @param code
* @param message
* @return
*/
public static Result<Object> failed(Integer code, String message) {
return new Result<>(code, message, null);
}
/**
* @param code
* @return
*/
public static Result<Object> failed(ResultCode code) {
return new Result<>(code.getCode(), code.getDesc(), null);
}
}
定义一个异常通用类:ApiException
@Getter
@Setter
public class ApiException extends RuntimeException {
private static final long serialVersionUID = -8412830185919566727L;
private Integer resultCode = ResultCode.UNKNOWN_CODE.getCode();
private String I18nKey = "";
public ApiException(String message) {
super(message);
}
public ApiException(Integer resultCode, String message) {
this(message);
this.resultCode = resultCode;
}
public ApiException(Integer resultCode) {
this(ResultCode.Fail.getDesc());
this.resultCode = resultCode;
}
public ApiException(Throwable cause) {
super(cause);
}
//支持传入code对象触发i18n数据
public ApiException(ResultCode code) {
this(code.getDesc());
this.resultCode = code.getCode();
this.I18nKey = code.getI18nKey();
}
}
定义异常拦截器:ApiExceptionHandler
/**
* 全局异常处理类
* 指定拦截异常的类型,被捕获的异常会调用handler方法,方法名自己随便定
*
**/
@RestControllerAdvice
public class ApiExceptionHandler {
/**
* ApiException异常处理
*
* @param e 异常
* @return 返回给前端的结果
*/
@ExceptionHandler(value = ApiException.class)
public Result<Object> apiExceptionHandler(ApiException e) {
String message = "";
String i18nKey = e.getI18nKey();
String i18nMessage = i18nUtils.getMessage(i18nKey);
if(i18nMessage.isEmpty()){
message = i18nKey;
}else{
message = i18nMessage;
}
if(!message.isEmpty()){
return Result.failed(e.getResultCode(), message);
}
return Result.failed(e.getResultCode(), e.getMessage());
}
}
定义 i18n 配置类:I18nConfig
@Slf4j
@Configuration
public class I18nConfig implements WebMvcConfigurer {
public static final String COOKIE_NAME = "locale";
@Resource
WebProperties webProperties;
@Bean(name = "messageSource")
public ResourceBundleMessageSource getMessageSource() throws Exception {
ResourceBundleMessageSource resourceBundleMessageSource = new ResourceBundleMessageSource();
resourceBundleMessageSource.setDefaultEncoding("UTF-8");
resourceBundleMessageSource.setBasenames("i18n/messages");
resourceBundleMessageSource.setCacheSeconds(3);
return resourceBundleMessageSource;
}
/**
* @return SessionLocaleResolver
*/
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
localeResolver.setDefaultLocale(getDefaultLocale());
return localeResolver;
}
/**
* Cookie方式
*/
@Bean
public LocaleResolver localeResolver2() {
CookieLocaleResolver clr = new CookieLocaleResolver();
clr.setCookieName(COOKIE_NAME);
//设置默认区域
clr.setDefaultLocale(getDefaultLocale());
//设置cookie有效期.
clr.setCookieMaxAge(3600);
return clr;
}
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
//对请求页面路径中的参数lang进行拦截
lci.setParamName("lang");
return lci;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
private Locale getDefaultLocale() {
Locale locale = webProperties.getLocale();
if (locale == null) {
locale = Locale.SIMPLIFIED_CHINESE;
}
return locale;
}
}
定义 i18n 消息内容处理器:I18nUtils
@Slf4j
@Component
public class I18nUtils {
@Resource
private MessageSource messageSource;
/**
* @param key:对应文本配置的key.
* @return 对应地区的语言消息字符串
*/
public String getMessage(String key) {
return this.getMessage(key, new Object[]{});
}
public String getMessage(String key, String defaultMessage) {
return this.getMessage(key, null, defaultMessage);
}
public String getMessage(String key, String defaultMessage, Locale locale) {
return this.getMessage(key, null, defaultMessage, locale);
}
public String getMessage(String key, Locale locale) {
return this.getMessage(key, null, "", locale);
}
public String getMessage(String key, Object[] args) {
return this.getMessage(key, args, "");
}
public String getMessage(String key, Object[] args, Locale locale) {
return this.getMessage(key, args, "", locale);
}
public String getMessage(String key, Object[] args, String defaultMessage) {
Locale locale = LocaleContextHolder.getLocale();
String message = this.getMessage(key, args, defaultMessage, locale);
return message;
}
public String getMessage(String key, Object[] args, String defaultMessage, Locale locale) {
return messageSource.getMessage(key, args, defaultMessage, locale);
}
}
项目集成
编写i18n翻译文件
resources/i18n/messages.properties
password.not.match=密码不匹配
resources/i18n/messages_zh_CN.properties
password.not.match=密码不匹配
resources/i18n/messages_en_US.properties
password.not.match=The password does not match
接口处理层抛出异常
if (dateList.isEmpty()) {
throw new ApiException(ResultCode.PASSWORD_NOT_MATCH);
}
数据返回