読者です 読者をやめる 読者になる 読者になる

かんがるーさんの日記

最近自分が興味をもったものを調べた時の手順等を書いています。今は Spring Boot をいじっています。

Spring Boot 1.3.x の Web アプリを 1.4.x へバージョンアップする ( 番外編 )( Optional をもう少しまともに使ってみる )

概要

記事一覧はこちらです。

src/main/java/ksbysample/webapp/lending/util/cookie/CookieUtils.java のソースに書いた Optional の使い方を見つけて、以前は全然使い方を理解できていなかったんだな。。。と思ったので、修正します。

Optional らしく書き直してみる

src/main/java/ksbysample/webapp/lending/util/cookie/CookieUtils.java で Optional を以下のように使っていたのですが、

    public static String getCookieValue(String cookieName, HttpServletRequest request) {
        Optional<String> result = Optional.empty();
        if (request != null) {
            Cookie[] cookies = request.getCookies();
            if (cookies != null) {
                result = Arrays.asList(cookies).stream()
                        .filter(cookie -> StringUtils.equals(cookie.getName(), cookieName))
                        .map(cookie -> cookie.getValue())
                        .findFirst();
            }
        }
        return result.orElse(null);
    }

上の内容なら if 文を使わずに、もう少しすっきりしたソースにできそうです。戻り値も StringOptional<String> に変更して書き直してみます。

    public static Optional<String> getCookieValue(String cookieName, HttpServletRequest request) {
        return Optional.ofNullable(request)
                .flatMap(req -> Optional.ofNullable(req.getCookies()))
                .flatMap(cookies -> Arrays.stream(cookies)
                            .filter(cookie -> StringUtils.equals(cookie.getName(), cookieName))
                            .map(Cookie::getValue)
                            .findFirst());
    }

CookieUtils#getCookieValue を呼び出している箇所も修正します。

src/main/java/ksbysample/webapp/lending/helper/url/UrlAfterLoginHelper.java は以下のように実装されているのを、

    public static String getUrlAfterLogin(Authentication authentication, HttpServletRequest request) {
        String targetUrl = WebSecurityConfig.DEFAULT_SUCCESS_URL;

        // 特定の権限を持っている場合には対応するURLへリダイレクトする
        GrantedAuthority roleAdmin = new SimpleGrantedAuthority("ROLE_ADMIN");
        if (authentication.getAuthorities().contains(roleAdmin)) {
            // 管理権限 ( ROLE_ADMIN ) を持っている場合には検索対象図書館登録画面へ遷移させる
            targetUrl = Constant.URL_AFTER_LOGIN_FOR_ROLE_ADMIN;
        }

        // LastLendingAppId Cookie に貸出申請ID をセットされている場合には貸出申請画面へリダイレクトさせる
        String cookieLastLendingAppId = CookieUtils.getCookieValue(CookieLastLendingAppId.COOKIE_NAME, request);
        if (StringUtils.isNotBlank(cookieLastLendingAppId)) {
            targetUrl = String.format("%s?lendingAppId=%s", Constant.URL_LENDINGAPP, cookieLastLendingAppId);
        }

        return targetUrl;
    }

以下のように修正します。

    public static String getUrlAfterLogin(Authentication authentication, HttpServletRequest request) {
        String targetUrl = WebSecurityConfig.DEFAULT_SUCCESS_URL;

        // 特定の権限を持っている場合には対応するURLへリダイレクトする
        GrantedAuthority roleAdmin = new SimpleGrantedAuthority("ROLE_ADMIN");
        if (authentication.getAuthorities().contains(roleAdmin)) {
            // 管理権限 ( ROLE_ADMIN ) を持っている場合には検索対象図書館登録画面へ遷移させる
            targetUrl = Constant.URL_AFTER_LOGIN_FOR_ROLE_ADMIN;
        }

        // LastLendingAppId Cookie に貸出申請ID をセットされている場合には貸出申請画面へリダイレクトさせる
        targetUrl = CookieUtils.getCookieValue(CookieLastLendingAppId.COOKIE_NAME, request)
                .map(cookieLastLendingAppId ->
                        String.format("%s?lendingAppId=%s", Constant.URL_LENDINGAPP, cookieLastLendingAppId))
                .orElse(targetUrl);

        return targetUrl;
    }

src/test/groovy/ksbysample/webapp/lending/util/cookie/CookieUtilsTest.groovy は以下のように実装されているのを、

    def "GetCookieValueのテスト"() {
        setup:
        def request = new MockHttpServletRequest()
        
        expect:
        Cookie cookieTest = new Cookie(CookieTest.COOKIE_NAME, "テスト")
        Cookie cookieSample = new Cookie(CookieSample.COOKIE_NAME, "サンプル")
        request.setCookies(cookieTest, cookieSample)
        CookieUtils.getCookieValue(CookieTest.COOKIE_NAME, request) == "テスト"
        CookieUtils.getCookieValue(CookieSample.COOKIE_NAME, request) == "サンプル"
    }

以下のように修正します。

    def "GetCookieValueのテスト"() {
        setup:
        def request = new MockHttpServletRequest()

        expect:
        Cookie cookieTest = new Cookie(CookieTest.COOKIE_NAME, "テスト")
        Cookie cookieSample = new Cookie(CookieSample.COOKIE_NAME, "サンプル")
        request.setCookies(cookieTest, cookieSample)
        CookieUtils.getCookieValue(CookieTest.COOKIE_NAME, request).get() == "テスト"
        CookieUtils.getCookieValue(CookieSample.COOKIE_NAME, request).get() == "サンプル"
        CookieUtils.getCookieValue(CookieTest.COOKIE_NAME, null) == Optional.empty()
        CookieUtils.getCookieValue("NotExistsCookie", request) == Optional.empty()
    }

最後にテストが通しで全て成功することを確認します。

f:id:ksby:20170407020451p:plain

履歴

2017/04/07
初版発行。