摘要:概述上一篇就默認的進行了分析,詳細請參考,本節我們繼續分析學習,主要分析解析器類繼承關系如下圖由上面類圖可知,繼承并實現接口,主要是操作的工具類,繼承接口,增加了信息操作。即通過實現的選擇。
概述
上一篇就Spring MVC默認的LocaleResovler(AcceptHeaderLocaleResolver)進行了分析,詳細請參考https://segmentfault.com/a/1190000014797899,本節我們繼續分析學習,主要分析CookieLocaleResolver
解析器(CookieLocaleResolver)CookieLocaleResolver類繼承關系如下圖:
由上面類圖可知,CookieLocaleResolver繼承CookieGenerator并實現LocaleContextResolver接口,CookieGenerator主要是操作Cookie的工具類,LocaleContextResolver繼承LacleResovler接口,增加了TimeZone信息操作。即通過Cookie實現Locale的選擇。
CookieLocaleResolver類的入口是resolveLocaleContext(final HttpServletRequest request),即Spring MVC接收到客戶端請求后,會調用此方法,源碼如下:
@Override public LocaleContext resolveLocaleContext(final HttpServletRequest request) { // 解析Cookie信息 parseLocaleCookieIfNecessary(request); // 返回Locale和TimeZone return new TimeZoneAwareLocaleContext() { @Override @Nullable public Locale getLocale() { return (Locale) request.getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME); } @Override @Nullable public TimeZone getTimeZone() { return (TimeZone) request.getAttribute(TIME_ZONE_REQUEST_ATTRIBUTE_NAME); } }; } private void parseLocaleCookieIfNecessary(HttpServletRequest request) { // 第一次請求為null if (request.getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME) == null) { Locale locale = null; // 地區 TimeZone timeZone = null; // 時區 // 獲取cookie的名稱,取自Spring MVC配置,默認為:CookieLocaleResolver.DEFAULT_COOKIE_NAME String cookieName = getCookieName(); if (cookieName != null) { // 根據名稱獲取當前請求中的Cookie(第一次訪問為null) Cookie cookie = WebUtils.getCookie(request, cookieName); if (cookie != null) { // 以下主要是從客戶端Cookie中解析出Locale String value = cookie.getValue(); String localePart = value; String timeZonePart = null; int spaceIndex = localePart.indexOf(" "); if (spaceIndex != -1) { localePart = value.substring(0, spaceIndex); timeZonePart = value.substring(spaceIndex + 1); } try { locale = (!"-".equals(localePart) ? parseLocaleValue(localePart) : null); if (timeZonePart != null) { timeZone = StringUtils.parseTimeZoneString(timeZonePart); } } catch (IllegalArgumentException ex) { if (request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) != null) { // Error dispatch: ignore locale/timezone parse exceptions if (logger.isDebugEnabled()) { logger.debug("Ignoring invalid locale cookie "" + cookieName + "" with value [" + value + "] due to error dispatch: " + ex.getMessage()); } } else { throw new IllegalStateException("Invalid locale cookie "" + cookieName + "" with value [" + value + "]: " + ex.getMessage()); } } if (logger.isDebugEnabled()) { logger.debug("Parsed cookie value [" + cookie.getValue() + "] into locale "" + locale + """ + (timeZone != null ? " and time zone "" + timeZone.getID() + """ : "")); } } } // 把Locale設置到請求的Attribute區,客戶端請求沒有攜帶Cookie,取Spring MVC中配置的defaultLocale request.setAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME, (locale != null ? locale : determineDefaultLocale(request))); request.setAttribute(TIME_ZONE_REQUEST_ATTRIBUTE_NAME, (timeZone != null ? timeZone : determineDefaultTimeZone(request))); } } // 設置Locale @Override public void setLocale(HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable Locale locale) { setLocaleContext(request, response, (locale != null ? new SimpleLocaleContext(locale) : null)); } // 主要是把Locale信息寫回客戶端 @Override public void setLocaleContext(HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable LocaleContext localeContext) { Assert.notNull(response, "HttpServletResponse is required for CookieLocaleResolver"); Locale locale = null; TimeZone timeZone = null; if (localeContext != null) { locale = localeContext.getLocale(); if (localeContext instanceof TimeZoneAwareLocaleContext) { timeZone = ((TimeZoneAwareLocaleContext) localeContext).getTimeZone(); } addCookie(response, (locale != null ? toLocaleValue(locale) : "-") + (timeZone != null ? " " + timeZone.getID() : "")); } else { removeCookie(response); } request.setAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME, (locale != null ? locale : determineDefaultLocale(request))); request.setAttribute(TIME_ZONE_REQUEST_ATTRIBUTE_NAME, (timeZone != null ? timeZone : determineDefaultTimeZone(request))); }實戰
項目結構
參考上一章https://segmentfault.com/a/1190000014797899中的項目結構,本章與其一致。
配置文件
在Spring MVC配置文件中配置資源加載以及CookieLocaleResolver Bean,配置如下:
屬性文件
參考上一章https://segmentfault.com/a/1190000014797899中的項目結構,本章與其一致。
控制器
編寫Controller控制器,以便測試,代碼如下:
/** * 通過Controller修改系統Locale信息 */ @GetMapping(value = "/setCookieLocale" , produces = "text/html;charset=UTF-8") @ResponseBody public String cookieLocaleResolver(HttpServletRequest request , HttpServletResponse response) { LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request); String locale = (String)request.getParameter("locale"); localeResolver.setLocale(request , response , parseLocaleValue(locale)); return "設置Locale成功"; } /** * 查看Locale信息 */ @GetMapping(value = "/getCookieLocale" , produces = "text/html;charset=UTF-8") @ResponseBody public String cookieLocaleResolver2(HttpServletRequest request , HttpServletResponse response) { String clientLocale = ""; Cookie[] cookies = request.getCookies(); if(cookies != null){ for(Cookie cookie : cookies){ clientLocale +=cookie.getName()+"="+cookie.getValue()+","; } } System.out.println(clientLocale); RequestContext requestContext = new RequestContext(request); String value = requestContext.getMessage("message.locale"); return "客戶端發送的Cookie有:"+clientLocale+" 當前使用的Locale是:" + requestContext.getLocale() + " 使用的資源Locale文件是:" + value ; }
測試
以chrome為客戶端,首先清除瀏覽器cookie,可在設置--內容管理--Cookie--查看所有Cookie和網站數據中查看是,如下圖:
我們的瀏覽器客戶端中的Cookie為空,我們還沒有到調用設置Locale的方法,此時我們訪問http://localhost:8089/getCookieLocale查看系統的Locale信息,如下圖:
由此可見,系統使用的在Spring MVC中配置的Locale信息(詳見上面的配置),并且請求頭和返回頭中都沒有Cookie數據(服務器沒有回寫Cookie給客戶端),接著我們調用http://localhost:8089/setCookieLocale?locale=en_US,此時,查看該請求的響應頭,如下圖:
由此可見,服務器端已經把Locale設置成功,并且通過response回寫給客戶端,當然也可查詢下瀏覽器中已有的Cookie,如下圖:
再次調用http://localhost:8089/getCookieLocale查看系統的Locale信息,如下圖:
當然可以把語言環境設置為了中文,如調用http://localhost:8089/setCookieLocale?locale=zh_CN即可。
至此,我們簡單分析了CookieLocaleResolver的核心源碼、實現以及驗證,此例僅僅是作為學習LocaleResolver,真實項目中可通過攔截器來實現,Spring提供了LocaleChangeInterceptor,也可自定義實現,其實就是重寫LocaleResolver接口setLocale方法。
總結CookieLocaleResolver可用于沒有用戶會話的無狀態應用程序
可與攔截器結合使用實現應用的國際化
最后創建了qq群方便大家交流,可掃描加入,同時也可加我qq:276420284,共同學習、共同進步,謝謝!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69341.html
摘要:概述我們繼續分析學習,本節我們分析使用的是。與類似,運用用戶會話實現功能。最后創建了群方便大家交流,可掃描加入,同時也可加我,共同學習共同進步,謝謝 概述 我們繼續分析學習Spring MVC LocaleResolver,本節我們分析使用的是SessionLocaleResolver。SessionLocaleResolver與CookieLocaleResolver類似,運用用戶會...
摘要:需求根據客戶端環境,界面顯示不同的國旗圖案。選擇的技術方案可利用提供的國際化和主題定制來解決。注意此時返回的中沒有國際化及主題相關的信息。修改請求參數的值為荷蘭,即后再發起請求,結果如下與預期一致,測試通過。 概述 以上分析了Spring MVC的LocaleResolver和ThemeResolver兩個策略解析器,在實際項目中很少使用,尤其是ThemeResolver,花精力去分析...
摘要:概述為我們提供國際化支持,通過設置系統的環境,根據運行環境使用不同的語言顯示。提供接口的作用是解析客戶端使用的地區,目的是為了根據這些信息實現視圖多語言即國際化。接口繼承接口,增加時區支持。 概述 Spring MVC為我們提供國際化支持,通過設置系統的環境,根據運行環境使用不同的語言顯示。Spring提供LocaleResolver接口的作用是解析客戶端使用的地區(Locale),目...
摘要:此解析器不能動態設置主題。實戰目標練習使用解析器,最終效果如下項目結構在下創建了主題文件夾及主題文件,下創建了靜態資源文件。是默認的解析器,再此配置是為了自定義屬性值,即屬性文件名稱。其實此解析器與的實現原理基本相同。 概述 主題就是系統的整體樣式或風格,可通過Spring MVC框架提供的主題(theme)設置應用的整體樣式風格,提高用戶體驗。Spring MVC的主題就是一些靜態資...
摘要:類繼承關系如下該類實現接口,實現解析設置主題功能繼承類,以具備操作功能。新增并更換一張不同的圖片。配置文件只要替換即可,代碼如下配置默認的主題文件視圖和控制器視圖和控制器代碼與上一章一致,參考上章代碼。 概述 上節介紹了SessionThemeResolver解析器,本章分析下CookieThemeResolver,兩個解析器實現的功能是一樣的,只是使用的主題載體有區別而已,Sessi...
閱讀 860·2021-11-25 09:44
閱讀 1063·2021-11-19 09:40
閱讀 7062·2021-09-07 10:23
閱讀 1975·2019-08-28 17:51
閱讀 1106·2019-08-26 10:59
閱讀 1928·2019-08-26 10:25
閱讀 3131·2019-08-23 18:22
閱讀 865·2019-08-23 16:58