配置
新增自定义i18n国际化拦截器
url参数优先,代码如下
public class CustomLocaleChangeInterceptor implements HandlerInterceptor {
/**
* 语言默认参数名
*/
public static final String DEFAULT_PARAM_NAME = "locale";
private String paramName = DEFAULT_PARAM_NAME;
@Nullable
private String[] httpMethods;
private boolean ignoreInvalidLocale = false;
/**
* 设置语言参数名
*
* @param paramName: 参数名
**/
public void setParamName(String paramName) {
this.paramName = paramName;
}
/**
* 获得语言参数名
*
* @return java.lang.String
**/
public String getParamName() {
return this.paramName;
}
/**
* 设置支持的请求方法
*
* @param httpMethods: 请求方法列表
**/
public void setHttpMethods(@Nullable String... httpMethods) {
this.httpMethods = httpMethods;
}
/**
* 获得支持的请求方法
*
* @return java.lang.String[]
**/
@Nullable
public String[] getHttpMethods() {
return this.httpMethods;
}
/**
* 设置是否忽略无效语言
*
* @param ignoreInvalidLocale: 是否忽略无效语言
**/
public void setIgnoreInvalidLocale(boolean ignoreInvalidLocale) {
this.ignoreInvalidLocale = ignoreInvalidLocale;
}
/**
* 获得是否忽略无效语言
*
* @return boolean
**/
public boolean isIgnoreInvalidLocale() {
return this.ignoreInvalidLocale;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
if (!checkHttpMethod(request.getMethod())) {
return true;
}
String newLocale = request.getParameter(getParamName());
if (newLocale == null) {
setLocale(request, response, request.getLocale());
return true;
}
setLocale(request, response, StringUtils.parseLocale(newLocale));
// Proceed in any case.
return true;
}
/**
* 设置语言
*
* @param request: 请求对象
* @param response: 返回对象
* @param locale: 语言
**/
private void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
if (localeResolver == null) {
throw new IllegalStateException(
"No LocaleResolver found: not in a DispatcherServlet request?");
}
try {
localeResolver.setLocale(request, response, locale);
} catch (IllegalArgumentException ex) {
if (isIgnoreInvalidLocale()) {
System.out.println("Ignoring invalid locale value [" + locale.toString() + "]: " + ex.getMessage());
} else {
throw ex;
}
}
}
/**
* 检查http请求
*
* @param currentMethod:当前请求
* @return boolean
**/
private boolean checkHttpMethod(String currentMethod) {
String[] configuredMethods = getHttpMethods();
if (ObjectUtils.isEmpty(configuredMethods)) {
return true;
}
for (String configuredMethod : configuredMethods) {
if (configuredMethod.equalsIgnoreCase(currentMethod)) {
return true;
}
}
return false;
}
}
webMvc配置
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
/**
* 默认解析器 其中locale表示默认语言
*/
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
localeResolver.setDefaultLocale(Locale.US);
return localeResolver;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
//自定义国际化拦截器
CustomLocaleChangeInterceptor localeInterceptor = new CustomLocaleChangeInterceptor();
localeInterceptor.setParamName("lang");
registry.addInterceptor(localeInterceptor);
}
}
application.yml
spring:
messages:
basename: i18n/messages
resources/i18n/messages.properties
service.customExecption=自定义错误,参数:{0}
service.i18nDemo=你好,世界。{0}
resources/i18n/messages_en_US.properties
service.customExecption=Custom error, parameter {0}
service.i18nDemo=Hello, world {0}
resources/i18n/messages_zh_CN.properties
service.customExecption=自定义错误,参数:{0}
service.i18nDemo=你好,世界。{0}
新增国际化工具类
@Component
public class MessageUtils {
private static MessageSource messageSource;
public MessageUtils(MessageSource messageSource) {
MessageUtils.messageSource = messageSource;
}
/**
* 获取单个国际化翻译值
*
* @param msgKey: 键
* @param args: 参数
* @return java.lang.String
**/
public static String get(String msgKey, Object[] args) {
try {
return messageSource.getMessage(msgKey, args, LocaleContextHolder.getLocale());
} catch (Exception e) {
e.printStackTrace();
return msgKey;
}
}
}
使用
@RestController
@RequestMapping("/i18n/")
public class I18nController {
/**
* 国际化测试
*
* @return java.lang.String
**/
@RequestMapping(value = "/message")
public String message() {
return MessageUtils.get("service.i18nDemo", new Object[]{"哈哈哈"});
}
/**
* 国际化测试
*
* @return java.lang.String
**/
@RequestMapping(value = "/throw_execption")
public String throwExecption() {
if(true){
throw new ServiceException("{service.customExecption}","测试参数");
}
return "ok";
}
}
在异常处理中使用国际化
自定义异常处理类
public class ServiceException extends RuntimeException {
private int code;
private String message;
private static final String MESSAGE_START_WITH = "{";
private static final String MESSAGE_END_WITH = "}";
private static MessageUtils messageUtils;
/**
* 初始化国际化配置
*
* @param messageSource: 国际化消息
**/
public static void initI18n(MessageSource messageSource) {
messageUtils = new MessageUtils(messageSource);
}
public ServiceException(int code, String message) {
this.code = code;
this.message = parseMessage(message);
}
public ServiceException(String message, Object... args) {
this.code = 502;
this.message = parseMessage(message, args);
}
/**
* 格式化消息
*
* @param message: 消息
* @param args: 参数
* @return java.lang.String
**/
private String parseMessage(final String message, Object... args) {
if (message.startsWith(MESSAGE_START_WITH) && message.endsWith(MESSAGE_END_WITH)) {
final String msgKey = message.substring(1, message.length() - 1);
return messageUtils.get(msgKey, args);
}
return String.format(message, args);
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
}
使用
@RestController
@RequestMapping("/i18n/")
public class I18nController {
/**
* 国际化测试
*
* @return java.lang.String
**/
@RequestMapping(value = "/throw_execption")
public String throwExecption() {
if(true){
throw new ServiceException("{service.customExecption}","测试参数");
}
return "ok";
}
}