背景:
前端需要进行切换语言的时候,后端提示语要根据前端的语言进行返回相应的中英文
实现方式通过Spring Boot实现国际化信息(i18n)
spring自带message获取类来进行切换
org.springframework.context.MessageSource
1首先在yaml中配置提示语文件spring目录下
spring
messages:
encoding: UTF-8
basename: i18n/messages
cache-second: 3600
2再次在resource下创建i18n文件夹下创建
messages提示语文件
我的properties文件,部分提示语
#system error
100001=系统错误
#100002=数据访问异常
#100003=数据不存在
#100004=URL格式错误
#100005=数据IO异常
100002=修改失败
100003=删除失败
100004=新增失败
100005=删除时备份失败
100006=查询失败
100007=数据库操作失败
100008=结束时间小于当前时间
100009=url格式错误
100010=拒绝访问
#api
110001=密码重置失败
110002=用户别名不能为空
110003=用户状态不能为空
110004=用户租户ID不能为空
110005=用户名 %s 已存在
110006=用户 %s 邮箱已存在
110007=用户 %s 手机号已存在
110008=邮箱不能为空
110009=系统角色不能停用、删除
110010=手机号不能为空
110011=无效手机号,请核验
110016=密码不可与以往三次密码一样
110017=密码格式错误
110018=用户未停用
110019=用户名不可与密码一样
110020=Excel上传解析失败
%s这个是占位符 通过string的String.format来替换
if (CollectionUtils.isNotEmpty(userDingTalk)) {
throw new BaseException(IBaseExceptionCode.API_USER_DINGTALKS_REPEAT,new String[]{user.getUserAlias()});
}
3.创建异常类BaseException
import lombok.Getter;
import java.io.Serializable;
@Getter
public class BaseException extends RuntimeException implements Serializable {
public final static long serialVersionUID = 1L;
private boolean debug = true;
private String trace;
private Object[] args;
private String code = IBaseExceptionCode.SYSTEM_ERROR;
public BaseException() {
}
public BaseException(String code) {
this.code = code;
}
public BaseException(String code, Object[] args) {
this.code = code;
this.args = args;
}
public BaseException(Throwable cause, String code) {
super(cause);
this.code = code;
}
}
4.创建统一结果返回类
import com.cloudwise.douc.commons.utils.MessageUtils;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import java.io.Serializable;
import static com.fasterxml.jackson.annotation.JsonInclude.Include.ALWAYS;
@Data
public class ResultEntity implements Serializable {
private static final String success_code = "100000";
protected ResultStatusEnum status;
@JsonInclude(ALWAYS)
protected Object msg;
protected Integer code;
public ResultEntity() {}
protected ResultEntity(String code, Object msg) {
this.code = Integer.valueOf(code);
this.msg = msg;
}
protected ResultEntity(ResultStatusEnum status, String code, Object msg) {
this.status = status;
this.msg = msg;
this.code = Integer.valueOf(code);
}
public static ResultEntity getSuccessResultEntity() {
return new ResultEntity(ResultStatusEnum.success, success_code, null);
}
public static ResultEntity getSuccessResultEntity(Object data) {
return new ResultDataEntity(ResultStatusEnum.success, success_code, null, data);
}
public static ResultEntity getNoticeResultEntity(Object msg) {
return new ResultEntity(ResultStatusEnum.notice, success_code, msg);
}
public static ResultEntity getSuccessResultEntityWithMsg(Object data, Object msg) {
return new ResultDataEntity(ResultStatusEnum.success, success_code, msg, data);
}
public static ResultEntity getFailResultEntity(String code, Object msg) {
return new ResultEntity(ResultStatusEnum.fail, code, msg);
}
public static ResultEntity getFailResultEntity(BaseException e) {
return ResultEntity.getFailResultEntity(e.getCode(), MessageUtils.getMsg(e.getCode()));
}
public static ResultEntity getFailResultEntity() {
return ResultEntity.getFailResultEntity(IBaseExceptionCode.SYSTEM_ERROR, MessageUtils.getMsg(IBaseExceptionCode.SYSTEM_ERROR));
}
public static ResultEntity getFailResultEntityWithData(String code, Object msg, Object data) {
return new ResultDataEntity(ResultStatusEnum.fail, code, msg, data);
}
public static ResultEntity getSuccessResultEntityWithMsg(Object data, int affectedCount, Object msg) {
return new ResultAffectedCountEntity(ResultStatusEnum.success, success_code, affectedCount, msg, data);
}
}
5创建一个异常code映射类,部分错误映射
public interface IBaseExceptionCode {
// 系统通用模块 1000**
String SUCCESS = "100000";
String SYSTEM_ERROR = "100001";
}
6.在校验不通过的地方抛出异常
if(department.getName().contains("/")){
throw new BaseException(IBaseExceptionCode.API_DEPARMENT_NAME_ERROR);
}
7写拦截转化类
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.stereotype.Controller;
import java.util.Locale;
@Controller
public class I18nMessages {
private static final Logger LOGGER = LoggerFactory
.getLogger(I18nMessages.class);
private MessageSource messageSource;
/**
* 初始化
*
* @return
*/
private MessageSource initMessageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("i18n/messages");
messageSource.setDefaultEncoding("UTF-8");
messageSource.setCacheSeconds(3600);
return messageSource;
}
/**
* 设置当前的返回信息
*
* @param language
* @param code
* @return
*/
public String getMessage(String language, String code) {
if (messageSource == null) {
messageSource = initMessageSource();
}
// String language = request.getHeader("language");
//默认没有就是请求地区的语言
Locale locale = getLocaleByLanguage(language);
String result = null;
try {
result = messageSource.getMessage(code, null, locale);
} catch (NoSuchMessageException e) {
LOGGER.error("Cannot find the error message of internationalization, return the original error message.");
}
if (result == null) {
return code;
}
return result;
}
public String getMsg(String language,BaseException e) {
return String.format(getMessage(language,e.getCode()), e.getArgs());
}
/**
* 获取
* @param language
* @return
*/
private Locale getLocaleByLanguage( String language){
Locale locale = null;
if (language == null) {
locale = Locale.CHINA;
} else if ("en_US".equals(language)) {
locale = Locale.ENGLISH;
} else if ("zh_CN".equals(language)) {
locale = Locale.CHINA;
}
//其余的不正确的默认就是本地的语言
else {
locale = Locale.CHINA;
}
return locale;
}
}
7.在需要返回的地方进行try catch捕获异常返回
e g: controller层 ,dubbo接口返回等
注入异常类
@Autowired
private I18nMessages i18n;
try {
user = userService.getUserInfo(userId);
if(department.getName().contains("/")){
throw new BaseException(IBaseExceptionCode.API_DEPARMENT_NAME_ERROR);
}
ValidatorUtils.validate(department, new String[]{"address"});
this.departmentService.addSubDepartment(department,accountId,userId);
LogUtil.printSystemLog (accountId,userId,user.getUserAlias(),userIp,ModuleConstant.DOUC_MODULE_DEPARTMENT, OperateEnum.COMMON_CREATE,department.getName(),PREFIX+PATH_V1+"/department/add",true,null,department);
return ResultEntity.getSuccessResultEntity("添加成功");
} catch (BaseException e) {
log.error("添加失败",e);
LogUtil.printSystemLog (accountId,userId,user.getUserAlias(),userIp,ModuleConstant.DOUC_MODULE_DEPARTMENT, OperateEnum.COMMON_CREATE,department.getName(),PREFIX+PATH_V1+"/department/add",false, MessageUtils.getMsg(e),department);
return ResultEntity.getFailResultEntity(e.getCode(), i18n.getMsg("zh_CN",e));
}
注:这个 zh_CN langue可以放到header中返回,接收一下
结果