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