成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

SpringMVC之源碼分析--LocaleResolver(二)

RichardXG / 3124人閱讀

摘要:概述上一篇就默認的進行了分析,詳細請參考,本節(jié)我們繼續(xù)分析學習,主要分析解析器類繼承關(guān)系如下圖由上面類圖可知,繼承并實現(xiàn)接口,主要是操作的工具類,繼承接口,增加了信息操作。即通過實現(xiàn)的選擇。

概述

上一篇就Spring MVC默認的LocaleResovler(AcceptHeaderLocaleResolver)進行了分析,詳細請參考https://segmentfault.com/a/1190000014797899,本節(jié)我們繼續(xù)分析學習,主要分析CookieLocaleResolver

解析器(CookieLocaleResolver)

CookieLocaleResolver類繼承關(guān)系如下圖:

由上面類圖可知,CookieLocaleResolver繼承CookieGenerator并實現(xiàn)LocaleContextResolver接口,CookieGenerator主要是操作Cookie的工具類,LocaleContextResolver繼承LacleResovler接口,增加了TimeZone信息操作。即通過Cookie實現(xiàn)Locale的選擇。

CookieLocaleResolver類的入口是resolveLocaleContext(final HttpServletRequest request),即Spring MVC接收到客戶端請求后,會調(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) {
    // 第一次請求為null
    if (request.getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME) == null) {
        Locale locale = null; // 地區(qū)
        TimeZone timeZone = null; // 時區(qū)

        // 獲取cookie的名稱,取自Spring MVC配置,默認為:CookieLocaleResolver.DEFAULT_COOKIE_NAME
        String cookieName = getCookieName();
        if (cookieName != null) {
            // 根據(jù)名稱獲取當前請求中的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設(shè)置到請求的Attribute區(qū),客戶端請求沒有攜帶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)));
}
實戰(zhàn)

項目結(jié)構(gòu)

參考上一章https://segmentfault.com/a/1190000014797899中的項目結(jié)構(gòu),本章與其一致。

配置文件

在Spring MVC配置文件中配置資源加載以及CookieLocaleResolver Bean,配置如下:



    
    
    
    
    



    
    
    
    
    




屬性文件

參考上一章https://segmentfault.com/a/1190000014797899中的項目結(jié)構(gòu),本章與其一致。

控制器

編寫Controller控制器,以便測試,代碼如下:

/**
 * 通過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+" 
當前使用的Locale是:" + requestContext.getLocale() + "
使用的資源Locale文件是:" + value ; }

測試

以chrome為客戶端,首先清除瀏覽器cookie,可在設(shè)置--內(nèi)容管理--Cookie--查看所有Cookie和網(wǎng)站數(shù)據(jù)中查看是,如下圖:

我們的瀏覽器客戶端中的Cookie為空,我們還沒有到調(diào)用設(shè)置Locale的方法,此時我們訪問http://localhost:8089/getCookieLocale查看系統(tǒng)的Locale信息,如下圖:

由此可見,系統(tǒng)使用的在Spring MVC中配置的Locale信息(詳見上面的配置),并且請求頭和返回頭中都沒有Cookie數(shù)據(jù)(服務(wù)器沒有回寫Cookie給客戶端),接著我們調(diào)用http://localhost:8089/setCookieLocale?locale=en_US,此時,查看該請求的響應(yīng)頭,如下圖:

由此可見,服務(wù)器端已經(jīng)把Locale設(shè)置成功,并且通過response回寫給客戶端,當然也可查詢下瀏覽器中已有的Cookie,如下圖:

再次調(diào)用http://localhost:8089/getCookieLocale查看系統(tǒng)的Locale信息,如下圖:

當然可以把語言環(huán)境設(shè)置為了中文,如調(diào)用http://localhost:8089/setCookieLocale?locale=zh_CN即可。

至此,我們簡單分析了CookieLocaleResolver的核心源碼、實現(xiàn)以及驗證,此例僅僅是作為學習LocaleResolver,真實項目中可通過攔截器來實現(xiàn),Spring提供了LocaleChangeInterceptor,也可自定義實現(xiàn),其實就是重寫LocaleResolver接口setLocale方法。

總結(jié)

CookieLocaleResolver可用于沒有用戶會話的無狀態(tài)應(yīng)用程序

可與攔截器結(jié)合使用實現(xiàn)應(yīng)用的國際化

最后創(chuàng)建了qq群方便大家交流,可掃描加入,同時也可加我qq:276420284,共同學習、共同進步,謝謝!

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/69341.html

相關(guān)文章

  • SpringMVC源碼分析--LocaleResolver(三)

    摘要:概述我們繼續(xù)分析學習,本節(jié)我們分析使用的是。與類似,運用用戶會話實現(xiàn)功能。最后創(chuàng)建了群方便大家交流,可掃描加入,同時也可加我,共同學習共同進步,謝謝 概述 我們繼續(xù)分析學習Spring MVC LocaleResolver,本節(jié)我們分析使用的是SessionLocaleResolver。SessionLocaleResolver與CookieLocaleResolver類似,運用用戶會...

    VishKozus 評論0 收藏0
  • SpringMVC源碼分析--LocaleResolver和ThemeResolver應(yīng)用

    摘要:需求根據(jù)客戶端環(huán)境,界面顯示不同的國旗圖案。選擇的技術(shù)方案可利用提供的國際化和主題定制來解決。注意此時返回的中沒有國際化及主題相關(guān)的信息。修改請求參數(shù)的值為荷蘭,即后再發(fā)起請求,結(jié)果如下與預期一致,測試通過。 概述 以上分析了Spring MVC的LocaleResolver和ThemeResolver兩個策略解析器,在實際項目中很少使用,尤其是ThemeResolver,花精力去分析...

    qpal 評論0 收藏0
  • SpringMVC源碼分析--LocaleResolver(一)

    摘要:概述為我們提供國際化支持,通過設(shè)置系統(tǒng)的環(huán)境,根據(jù)運行環(huán)境使用不同的語言顯示。提供接口的作用是解析客戶端使用的地區(qū),目的是為了根據(jù)這些信息實現(xiàn)視圖多語言即國際化。接口繼承接口,增加時區(qū)支持。 概述 Spring MVC為我們提供國際化支持,通過設(shè)置系統(tǒng)的環(huán)境,根據(jù)運行環(huán)境使用不同的語言顯示。Spring提供LocaleResolver接口的作用是解析客戶端使用的地區(qū)(Locale),目...

    HtmlCssJs 評論0 收藏0
  • SpringMVC源碼分析--ThemeResolver(一)

    摘要:此解析器不能動態(tài)設(shè)置主題。實戰(zhàn)目標練習使用解析器,最終效果如下項目結(jié)構(gòu)在下創(chuàng)建了主題文件夾及主題文件,下創(chuàng)建了靜態(tài)資源文件。是默認的解析器,再此配置是為了自定義屬性值,即屬性文件名稱。其實此解析器與的實現(xiàn)原理基本相同。 概述 主題就是系統(tǒng)的整體樣式或風格,可通過Spring MVC框架提供的主題(theme)設(shè)置應(yīng)用的整體樣式風格,提高用戶體驗。Spring MVC的主題就是一些靜態(tài)資...

    Ocean 評論0 收藏0
  • SpringMVC源碼分析--ThemeResolver(三)

    摘要:類繼承關(guān)系如下該類實現(xiàn)接口,實現(xiàn)解析設(shè)置主題功能繼承類,以具備操作功能。新增并更換一張不同的圖片。配置文件只要替換即可,代碼如下配置默認的主題文件視圖和控制器視圖和控制器代碼與上一章一致,參考上章代碼。 概述 上節(jié)介紹了SessionThemeResolver解析器,本章分析下CookieThemeResolver,兩個解析器實現(xiàn)的功能是一樣的,只是使用的主題載體有區(qū)別而已,Sessi...

    OldPanda 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<