买服饰网站建设,订单系统单页面网站怎么做,太原网站制作推荐,黄山网站建设哪家强LocaleResolver 组件LocaleResolver 组件#xff0c;本地化#xff08;国际化#xff09;解析器#xff0c;提供国际化支持回顾先来回顾一下在 DispatcherServlet 中处理请求的过程中哪里使用到 LocaleResolver 组件#xff0c;可以回到《一个请求的旅行过程》中的 Dispat…LocaleResolver 组件LocaleResolver 组件本地化国际化解析器提供国际化支持回顾先来回顾一下在 DispatcherServlet 中处理请求的过程中哪里使用到 LocaleResolver 组件可以回到《一个请求的旅行过程》中的 DispatcherServlet 的 processDispatchResult 方法中看看如下private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,Nullable HandlerExecutionChain mappedHandler, Nullable ModelAndView mv,Nullable Exception exception) throws Exception {// ... 省略相关代码// 3 是否进行页面渲染if (mv ! null !mv.wasCleared()) {// 3.1 渲染页面render(mv, request, response);// 3.2 清理请求中的错误消息属性// 因为上述的情况二中 processHandlerException 会通过 WebUtils 设置错误消息属性所以这里得清理一下if (errorView) {WebUtils.clearErrorRequestAttributes(request);}}// ... 省略相关代码
}protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {// Determine locale for request and apply it to the response.// 1 解析 request 中获得 Locale 对象并设置到 response 中Locale locale (this.localeResolver ! null ? this.localeResolver.resolveLocale(request) : request.getLocale());response.setLocale(locale);// ... 省略相关代码// 获得 View 对象View view;String viewName mv.getViewName();// ... 省略相关代码view mv.getView();// ... 省略相关代码try {// 3 设置响应的状态码if (mv.getStatus() ! null) {response.setStatus(mv.getStatus().value());}// 4 渲染页面view.render(mv.getModelInternal(), request, response);}// ... 省略相关代码
}
在执行完handler处理器后需要对返回的 ModelAndView 对象进行处理可能需要调用 render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) 方法渲染页面可以看到需要先通过 LocaleResolver 从请求中解析出 java.util.Locale 对象LocaleResolver 接口org.springframework.web.servlet.LocaleResolver本地化国际化解析器提供国际化支持代码如下public interface LocaleResolver {/*** 从请求中解析出要使用的语言。例如请求头的 Accept-Language*/Locale resolveLocale(HttpServletRequest request);/*** 设置请求所使用的语言*/void setLocale(HttpServletRequest request, Nullable HttpServletResponse response, Nullable Locale locale);
}
LocaleResolver 接口体系的结构如下初始化过程在 DispatcherServlet 的 initLocaleResolver(ApplicationContext context) 方法初始化 LocaleResolver 组件方法如下private void initLocaleResolver(ApplicationContext context) {try {// 从上下文中获取Bean名称为localeResolver的对象this.localeResolver context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class);if (logger.isTraceEnabled()) {logger.trace(Detected this.localeResolver);}else if (logger.isDebugEnabled()) {logger.debug(Detected this.localeResolver.getClass().getSimpleName());}}catch (NoSuchBeanDefinitionException ex) {// We need to use the default./*** 从配置文件中获取默认的 {link org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver}*/this.localeResolver getDefaultStrategy(context, LocaleResolver.class);if (logger.isTraceEnabled()) {logger.trace(No LocaleResolver LOCALE_RESOLVER_BEAN_NAME : using default [ this.localeResolver.getClass().getSimpleName() ]);}}
}获得 Bean 名称为 localeResolver类型为 LocaleResolver 的 Bean 将其设置为 localeResolver如果未获得到则获得默认配置的 LocaleResolver 实现类调用 getDefaultStrategies(ApplicationContext context, ClassT strategyInterface) 方法就是从 DispatcherServlet.properties 文件中读取 LocaleResolver 的默认实现类如下org.springframework.web.servlet.LocaleResolverorg.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver我看了一下Spring Boot 没有提供其他的实现类默认也是这个AcceptHeaderLocaleResolverorg.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver实现 LocaleResolver 接口通过检验 HTTP 请求的Accept-Language头部来解析区域默认的实现类构造方法public class AcceptHeaderLocaleResolver implements LocaleResolver {private final ListLocale supportedLocales new ArrayList(4);Nullableprivate Locale defaultLocale;
}上面两个属性默认都没有设置值resolveLocale实现 resolveLocale(HttpServletRequest request) 方法从请求中解析出 java.util.Locale 对象方法如下Override
public Locale resolveLocale(HttpServletRequest request) {// 1 获取默认的语言环境Locale defaultLocale getDefaultLocale();// 2 如果请求头 Accept-Language 为空且默认语言环境不为空则返回默认的if (defaultLocale ! null request.getHeader(Accept-Language) null) {return defaultLocale;}// 3 从请求中获取 Locale 对象 requestLocaleLocale requestLocale request.getLocale();// 4 获取当前支持的 supportedLocales 集合ListLocale supportedLocales getSupportedLocales();// 5 如果支持的 supportedLocales 集合为空或者包含请求中的 requestLocale 则返回请求中的语言环境if (supportedLocales.isEmpty() || supportedLocales.contains(requestLocale)) {return requestLocale;}// 6 从请求中的 Locale 们和支持的 Locale 集合进行匹配Locale supportedLocale findSupportedLocale(request, supportedLocales);// 7 如果匹配到了则直接返回匹配结果if (supportedLocale ! null) {return supportedLocale;}// 8 默认的 defaultLocale 不为空则直接返回否则返回请求中获取到的 requestLocale 对象return (defaultLocale ! null ? defaultLocale : requestLocale);
}获取默认的语言环境如果请求头 Accept-Language 为空且默认语言环境不为空则返回默认对象 defaultLocale从请求中获取 Locale 对象 requestLocale调用 getSupportedLocales 方法获取当前支持的 supportedLocales 集合默认为空如果支持的 supportedLocales 集合为空或者包含请求中的 requestLocale 则返回请求中的语言环境调用 findSupportedLocale(HttpServletRequest request, ListLocale supportedLocales) 方法从请求中的 Locale 们和支持的 Locale 集合进行匹配如下Nullable
private Locale findSupportedLocale(HttpServletRequest request, ListLocale supportedLocales) {EnumerationLocale requestLocales request.getLocales();Locale languageMatch null;while (requestLocales.hasMoreElements()) {Locale locale requestLocales.nextElement();if (supportedLocales.contains(locale)) {if (languageMatch null || languageMatch.getLanguage().equals(locale.getLanguage())) {// Full match: language country, possibly narrowed from earlier language-only matchreturn locale;}}else if (languageMatch null) {// Lets try to find a language-only match as a fallbackfor (Locale candidate : supportedLocales) {if (!StringUtils.hasLength(candidate.getCountry()) candidate.getLanguage().equals(locale.getLanguage())) {languageMatch candidate;break;}}}}return languageMatch;
}如果匹配到了则直接返回匹配结果默认的 defaultLocale 不为空则直接返回否则返回请求中获取到的 requestLocale 对象默认情况下supportedLocales 与defaultLocale 属性都是空的所以 AcceptHeaderLocaleResolver 使用Accept-Language 请求头来构造 Locale 对象例如请求的请求头中会有zh-CN,zh;q0.9数据那么这里解析出来 Locale 对象就对应languagezh regionCN数据总结本文分析了 LocaleResolver 组件本地化国际化解析器提供国际化支持。笔者实际上没有接触过该组件因为目前的项目大多数都已经前后端分离了这里只是浅显的介绍了该接口.