Spring Boot Ajax/JavaScript連携

Spring Bootでのウィンドウを開くタイミングのエラー処理を実装してみた

今回は、Spring Bootのウィンドウを開くタイミングでエラーが発生した場合に、開く予定だったウィンドウを閉じ、その親画面にエラーメッセージを表示してみたので、そのサンプルプログラムを共有する。

前提条件

下記記事の実装が完了していること。

Spring Bootでのウィンドウを開く処理をJavaScriptで実施してみたウィンドウを開く処理は、GETリクエスト・POSTリクエストのどちらであっても、JavaScriptで実装できる。今回は、GETリクエス...

サンプルプログラムの作成

作成したサンプルプログラムの構成は以下の通り。
サンプルプログラムの構成
なお、上記の赤枠は、前提条件のプログラムから追加/変更したプログラムである。

初期表示画面のHTMLは以下の通りで、エラーメッセージを表示する領域と、「新規ウィンドウをオープン時にエラー(POST)」ボタンを追加している。

<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <link th:href="@{/demo.css}" rel="stylesheet" type="text/css" />
    <script type="text/javascript" th:src="@{/demo.js}"></script>
    <title>index page</title>
</head>
<body>
    <div id="errList">
        <ul>
            <li th:each="err : ${errList}" th:text="${err}" class="errorMessage"></li>
        </ul>
    </div>
    <form th:action="@{/openWinByGet}" method="GET" name="formGet">
        <input type="button" value="新規ウィンドウをオープン(GET)"
               onclick="openWin('formGet');" />
    </form>
    <br/><br/>
    <form th:action="@{/openWinByPost}" method="POST" name="formPost">
        <input type="button" value="新規ウィンドウをオープン(POST)"
               onclick="openWin('formPost');" />
    </form>
    <br/><br/>
    <form th:action="@{/openWinByPostErr}" method="POST" name="formPostErr">
        <input type="button" value="新規ウィンドウをオープン時にエラー(POST)"
               onclick="openWin('formPostErr');" />
    </form>
</body>
</html>

「新規ウィンドウをオープン時にエラー(POST)」ボタンを押下したタイミングで開く画面のHTMLは以下の通りで、この画面をロードしたタイミングで、printOpenErrMsg関数を呼ぶようにしている。

<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <link th:href="@{/demo.css}" rel="stylesheet" type="text/css" />
    <script type="text/javascript" th:src="@{/demo.js}"></script>
    <script type="text/javascript">
        //本画面ロード時に、エラーメッセージがあればエラーメッセージを親画面に転記し、
        //本画面を閉じる
        window.onload = function(){
            printOpenErrMsg();
        }
    </script>
    <title>index page</title>
</head>
<body>
    <div id="errList">
        <ul>
            <li th:each="err : ${errList}" th:text="${err}" class="errorMessage"></li>
        </ul>
    </div>
    POSTリクエストで新規ウィンドウをオープンしました。(エラー時)
</body>
</html>



JavaScriptの内容は以下の通りで、printOpenErrMsgメソッドで、ウィンドウを開くタイミングでエラーが発生した場合に、開く予定だったウィンドウを閉じ、DOM操作によってその親画面にエラーメッセージを表示する処理を行っている。

'use strict';

//フォーム名を指定して新しいウィンドウを開く
function openWin(formName){
    let form = document.forms[formName];
    if(!form){
        alert('指定したフォームが取得できませんでした');
        return;
    }
    let win = window.open('about:blank', formName);
    form.target = formName;
    form.submit();
    win.focus();
}
//子画面のエラーメッセージを親画面に転記
function printOpenErrMsg(){
    let errList = document.getElementById('errList');
    if(errList){
        let errMessages = errList.getElementsByTagName('li');
        //子画面にエラーメッセージがある場合
        if(errMessages && errMessages.length > 0){
            //親画面のエラーメッセージリストを取得し初期化後、メッセージを追加
            let errListP = window.opener.document.getElementById('errList');
            if(errListP){
                errListP.innerHTML = "";
                let errListUlP = document.createElement("ul");
                errListP.appendChild(errListUlP)
                for(let i = 0; i < errMessages.length; i++){
                    let msg = errMessages[i].textContent;
                    let errListLiP = document.createElement("li");
                    errListLiP.innerHTML = msg;
                    errListLiP.classList.add('errorMessage');
                    errListUlP.appendChild(errListLiP);
                }
            }
            //子画面を閉じる
            window.close();
        }
    }
}

CSSファイルの内容は以下の通りで、エラーメッセージを赤字で表示するようにしている。

.errorMessage{
    color: #FF0000;
}



その他、コントローラクラスの内容は以下の通りで、「新規ウィンドウをオープン時にエラー(POST)」ボタン押下時に、エラーメッセージを設定するようにしている。

package com.example.demo;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

import java.util.ArrayList;
import java.util.List;

@Controller
public class DemoController {

    /**
     * 初期表示画面を開く
     * @return 初期表示画面へのパス
     */
    @GetMapping("/")
    public String index(){
        return "index";
    }

    /**
     * 新規画面(GETリクエスト用)を開く
     * @return 新規画面(GETリクエスト用)
     */
    @GetMapping("/openWinByGet")
    public String openWinByGet(){
        return "new_window1";
    }

    /**
     * 新規画面(POSTリクエスト用)を開く
     * @return 新規画面(POSTリクエスト用)
     */
    @PostMapping("/openWinByPost")
    public String openWinByPost(){
        return "new_window2";
    }

    /**
     * 新規画面(POSTリクエスト用)を開く際にエラー
     * @return 新規画面(POSTリクエスト用_エラー)
     */
    @PostMapping("/openWinByPostErr")
    public String openWinByPostErr(Model model){
        List<String> errList = new ArrayList<>();
        errList.add("新規ウィンドウオープン時のエラーメッセージ1");
        errList.add("新規ウィンドウオープン時のエラーメッセージ2");
        errList.add("新規ウィンドウオープン時のエラーメッセージ3");
        model.addAttribute("errList", errList);
        return "new_window3";
    }
}

その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/spring-boot-js-openwindow-err/demo



サンプルプログラムの実行結果

サンプルプログラムの実行結果は、以下の通り。

1) Spring Bootアプリケーションを起動し、「http://(サーバー名):(ポート番号)/」とアクセスすると、以下の画面が表示される。
サンプルプログラムの実行結果_1

2) 「新規ウィンドウをオープン時にエラー(POST)」ボタンを押下すると、開く予定だったウィンドウを閉じ、初期表示画面にエラーメッセージが表示されることが確認できる。
サンプルプログラムの実行結果_2_1

サンプルプログラムの実行結果_2_2

要点まとめ

  • ウィンドウを開くタイミングでエラーが発生した場合に、開く予定だったウィンドウを閉じ、その親画面にDOM操作によってエラーメッセージを表示する処理を実装することができる。