spring国际化locale的代码原理以及拓展配置
原理
两种不同的LocaleResolve
LocaleResolver
public interface LocaleResolver {
//解析Lcoale
Locale resolveLocale(HttpServletRequest request);
//设置Locale
void setLocale(HttpServletRequest request, @Nullable HttpServletResponse response,
@Nullable Locale locale);
LocaleContextResolver多了解析时区的功能
/**
* Extension of {@link LocaleResolver}, adding support for a rich locale context
* (potentially including locale and time zone information).
*/
public interface LocaleContextResolver extends LocaleResolver {
LocaleContext resolveLocaleContext(HttpServletRequest request);
void setLocaleContext(HttpServletRequest request,
@Nullable HttpServletResponse response,
@Nullable LocaleContext localeContext);
LocaleContext
public interface LocaleContext {
@Nullable
Locale getLocale();
}
在DispatchServlet配置新的LocaleContext
//每次请求都会解析配置新的LocaleContext
@Override
protected LocaleContext buildLocaleContext(final HttpServletRequest request) {
LocaleResolver lr = this.localeResolver;
//根据locale不同等级进行调用
if (lr instanceof LocaleContextResolver) {
return ((LocaleContextResolver) lr).resolveLocaleContext(request);
}
else {
//lumbda表达式返回一个类(重写了LcoaleContext的getLocale方法)
return () -> (lr != null ? lr.resolveLocale(request) : request.getLocale());
}
}
通过rend方法,使用response渲染
protected void render(ModelAndView mv, HttpServletRequest request,
HttpServletResponse response) throws Exception {
// Determine locale for request and apply it to the response.
Locale locale =
(this.localeResolver != null ?
this.localeResolver.resolveLocale(request) : request.getLocale());
response.setLocale(locale);//在response方法写出Locale
实现
/**
*自定义的LocaleReslover和Controller(可以根据URL设置Locale并且放在Session当中)
*/
public class ParamLocaleResolver implements LocaleResolver {
//Session域的键的名称
public static final String LOCALE_SESSION_ATTRIBUTE_NAME
= ParamLocaleResolver.class.getName() + ".LOCALE";
private String localeAttributeName = LOCALE_SESSION_ATTRIBUTE_NAME;
@Override
public Locale resolveLocale(HttpServletRequest request) {
//每次从Session当中获取,不需要重新创建。
Locale locale
= ((Locale) WebUtils.getSessionAttribute(request, localeAttributeName));
if (locale == null) {
//第一次将浏览器默认的locale写入Session
locale = request.getLocale();
WebUtils.setSessionAttribute(request, localeAttributeName, locale);
}
return locale;
}
@Override
public void setLocale(HttpServletRequest request,
HttpServletResponse response, Locale locale) {
if (locale != null) {
//重新写入Session当中
WebUtils.setSessionAttribute(request, localeAttributeName, locale);
}
}
}
@Controller
public class LocaleController {
@RequestMapping("/setLocal")
public String setLocale(HttpServletRequest request,
@Autowired ParamLocaleResolver resolver) {
//根据参数获取Locale
String param = request.getParameter("locale");
if (!StringUtils.isEmpty(param)) {
String[] split = param.split("_");
Locale locale = new Locale(split[0], split[1]);
//locale解析成功设置新的locale
resolver.setLocale(request, null, locale);
}
return "login";
}
}
配置
(
applications.properties
# 默认放在类路径下的 message.properties
#eg:classpath:/message/login.properties basename写为message.login (会将‘.’解析为 ‘/’)
spring.messages.basename=message