摘要:概述上一篇就默認(rèn)的進(jìn)行了分析,詳細(xì)請(qǐng)參考,本節(jié)我們繼續(xù)分析學(xué)習(xí),主要分析解析器類繼承關(guān)系如下圖由上面類圖可知,繼承并實(shí)現(xiàn)接口,主要是操作的工具類,繼承接口,增加了信息操作。即通過(guò)實(shí)現(xiàn)的選擇。
概述
上一篇就Spring MVC默認(rèn)的LocaleResovler(AcceptHeaderLocaleResolver)進(jìn)行了分析,詳細(xì)請(qǐng)參考https://segmentfault.com/a/1190000014797899,本節(jié)我們繼續(xù)分析學(xué)習(xí),主要分析CookieLocaleResolver
解析器(CookieLocaleResolver)CookieLocaleResolver類繼承關(guān)系如下圖:
由上面類圖可知,CookieLocaleResolver繼承CookieGenerator并實(shí)現(xiàn)LocaleContextResolver接口,CookieGenerator主要是操作Cookie的工具類,LocaleContextResolver繼承LacleResovler接口,增加了TimeZone信息操作。即通過(guò)Cookie實(shí)現(xiàn)Locale的選擇。
CookieLocaleResolver類的入口是resolveLocaleContext(final HttpServletRequest request),即Spring MVC接收到客戶端請(qǐng)求后,會(huì)調(diào)用此方法,源碼如下:
@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) { // 第一次請(qǐng)求為null if (request.getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME) == null) { Locale locale = null; // 地區(qū) TimeZone timeZone = null; // 時(shí)區(qū) // 獲取cookie的名稱,取自Spring MVC配置,默認(rèn)為:CookieLocaleResolver.DEFAULT_COOKIE_NAME String cookieName = getCookieName(); if (cookieName != null) { // 根據(jù)名稱獲取當(dāng)前請(qǐng)求中的Cookie(第一次訪問(wèn)為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設(shè)置到請(qǐng)求的Attribute區(qū),客戶端請(qǐng)求沒(méi)有攜帶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))); } } // 設(shè)置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))); }實(shí)戰(zhàn)
項(xiàng)目結(jié)構(gòu)
參考上一章https://segmentfault.com/a/1190000014797899中的項(xiàng)目結(jié)構(gòu),本章與其一致。
配置文件
在Spring MVC配置文件中配置資源加載以及CookieLocaleResolver Bean,配置如下:
屬性文件
參考上一章https://segmentfault.com/a/1190000014797899中的項(xiàng)目結(jié)構(gòu),本章與其一致。
控制器
編寫Controller控制器,以便測(cè)試,代碼如下:
/** * 通過(guò)Controller修改系統(tǒng)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 "設(shè)置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 "客戶端發(fā)送的Cookie有:"+clientLocale+" 當(dāng)前使用的Locale是:" + requestContext.getLocale() + " 使用的資源Locale文件是:" + value ; }
測(cè)試
以chrome為客戶端,首先清除瀏覽器cookie,可在設(shè)置--內(nèi)容管理--Cookie--查看所有Cookie和網(wǎng)站數(shù)據(jù)中查看是,如下圖:
我們的瀏覽器客戶端中的Cookie為空,我們還沒(méi)有到調(diào)用設(shè)置Locale的方法,此時(shí)我們?cè)L問(wèn)http://localhost:8089/getCookieLocale查看系統(tǒng)的Locale信息,如下圖:
由此可見,系統(tǒng)使用的在Spring MVC中配置的Locale信息(詳見上面的配置),并且請(qǐng)求頭和返回頭中都沒(méi)有Cookie數(shù)據(jù)(服務(wù)器沒(méi)有回寫Cookie給客戶端),接著我們調(diào)用http://localhost:8089/setCookieLocale?locale=en_US,此時(shí),查看該請(qǐng)求的響應(yīng)頭,如下圖:
由此可見,服務(wù)器端已經(jīng)把Locale設(shè)置成功,并且通過(guò)response回寫給客戶端,當(dāng)然也可查詢下瀏覽器中已有的Cookie,如下圖:
再次調(diào)用http://localhost:8089/getCookieLocale查看系統(tǒng)的Locale信息,如下圖:
當(dāng)然可以把語(yǔ)言環(huán)境設(shè)置為了中文,如調(diào)用http://localhost:8089/setCookieLocale?locale=zh_CN即可。
至此,我們簡(jiǎn)單分析了CookieLocaleResolver的核心源碼、實(shí)現(xiàn)以及驗(yàn)證,此例僅僅是作為學(xué)習(xí)LocaleResolver,真實(shí)項(xiàng)目中可通過(guò)攔截器來(lái)實(shí)現(xiàn),Spring提供了LocaleChangeInterceptor,也可自定義實(shí)現(xiàn),其實(shí)就是重寫LocaleResolver接口setLocale方法。
總結(jié)CookieLocaleResolver可用于沒(méi)有用戶會(huì)話的無(wú)狀態(tài)應(yīng)用程序
可與攔截器結(jié)合使用實(shí)現(xiàn)應(yīng)用的國(guó)際化
最后創(chuàng)建了qq群方便大家交流,可掃描加入,同時(shí)也可加我qq:276420284,共同學(xué)習(xí)、共同進(jìn)步,謝謝!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/69341.html
摘要:概述我們繼續(xù)分析學(xué)習(xí),本節(jié)我們分析使用的是。與類似,運(yùn)用用戶會(huì)話實(shí)現(xiàn)功能。最后創(chuàng)建了群方便大家交流,可掃描加入,同時(shí)也可加我,共同學(xué)習(xí)共同進(jìn)步,謝謝 概述 我們繼續(xù)分析學(xué)習(xí)Spring MVC LocaleResolver,本節(jié)我們分析使用的是SessionLocaleResolver。SessionLocaleResolver與CookieLocaleResolver類似,運(yùn)用用戶會(huì)...
摘要:需求根據(jù)客戶端環(huán)境,界面顯示不同的國(guó)旗圖案。選擇的技術(shù)方案可利用提供的國(guó)際化和主題定制來(lái)解決。注意此時(shí)返回的中沒(méi)有國(guó)際化及主題相關(guān)的信息。修改請(qǐng)求參數(shù)的值為荷蘭,即后再發(fā)起請(qǐng)求,結(jié)果如下與預(yù)期一致,測(cè)試通過(guò)。 概述 以上分析了Spring MVC的LocaleResolver和ThemeResolver兩個(gè)策略解析器,在實(shí)際項(xiàng)目中很少使用,尤其是ThemeResolver,花精力去分析...
摘要:概述為我們提供國(guó)際化支持,通過(guò)設(shè)置系統(tǒng)的環(huán)境,根據(jù)運(yùn)行環(huán)境使用不同的語(yǔ)言顯示。提供接口的作用是解析客戶端使用的地區(qū),目的是為了根據(jù)這些信息實(shí)現(xiàn)視圖多語(yǔ)言即國(guó)際化。接口繼承接口,增加時(shí)區(qū)支持。 概述 Spring MVC為我們提供國(guó)際化支持,通過(guò)設(shè)置系統(tǒng)的環(huán)境,根據(jù)運(yùn)行環(huán)境使用不同的語(yǔ)言顯示。Spring提供LocaleResolver接口的作用是解析客戶端使用的地區(qū)(Locale),目...
摘要:此解析器不能動(dòng)態(tài)設(shè)置主題。實(shí)戰(zhàn)目標(biāo)練習(xí)使用解析器,最終效果如下項(xiàng)目結(jié)構(gòu)在下創(chuàng)建了主題文件夾及主題文件,下創(chuàng)建了靜態(tài)資源文件。是默認(rèn)的解析器,再此配置是為了自定義屬性值,即屬性文件名稱。其實(shí)此解析器與的實(shí)現(xiàn)原理基本相同。 概述 主題就是系統(tǒng)的整體樣式或風(fēng)格,可通過(guò)Spring MVC框架提供的主題(theme)設(shè)置應(yīng)用的整體樣式風(fēng)格,提高用戶體驗(yàn)。Spring MVC的主題就是一些靜態(tài)資...
摘要:類繼承關(guān)系如下該類實(shí)現(xiàn)接口,實(shí)現(xiàn)解析設(shè)置主題功能繼承類,以具備操作功能。新增并更換一張不同的圖片。配置文件只要替換即可,代碼如下配置默認(rèn)的主題文件視圖和控制器視圖和控制器代碼與上一章一致,參考上章代碼。 概述 上節(jié)介紹了SessionThemeResolver解析器,本章分析下CookieThemeResolver,兩個(gè)解析器實(shí)現(xiàn)的功能是一樣的,只是使用的主題載體有區(qū)別而已,Sessi...
閱讀 926·2021-11-25 09:44
閱讀 1172·2021-11-19 09:40
閱讀 7390·2021-09-07 10:23
閱讀 2052·2019-08-28 17:51
閱讀 1193·2019-08-26 10:59
閱讀 1995·2019-08-26 10:25
閱讀 3260·2019-08-23 18:22
閱讀 935·2019-08-23 16:58