HTTPは、Webサーバーとクライアント(ブラウザ)の間で、ウェブページを送受信するためのプロトコルで、以下のページに示すように、HTTPメッセージはヘッダーとボディを含んでいる。
http://www.tohoho-web.com/ex/http.htm
今回は、HTTPボディでなくHTTPヘッダーに値を設定し取得するサンプルプログラムを作成してみたので、共有する。
前提条件
下記記事の実装が完了していること。
サンプルプログラムの作成
作成したサンプルプログラムの構成は以下の通り。
なお、上記の赤枠は、前提条件のプログラムから追加/変更したプログラムである。
まず、ログインFormの内容は以下の通りで、ユーザーID・ユーザー名・パスワードをもっている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | package com.example.demo; import lombok.Data; @Data public class LoginForm { /** ユーザーID */ private String userId; /** ユーザー名 */ private String userName; /** パスワード */ private String userPass; } |
次に、ログイン画面のHTMLの内容は以下の通りで、ログインボタンが押下されたタイミングで、JavaScriptのlogin関数を呼び出すようになっている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <!DOCTYPE html> <html lang="ja" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <script type="text/javascript" th:src="@{/login.js}"></script> <title>index page</title> </head> <body> <p>下記必要事項を記載の上、ログインボタンを押下してください。</p><br/> <form th:object="${loginForm}"> ユーザーID: <input type="text" th:value="*{userId}" th:field="*{userId}" /> <br/> ユーザー名: <input type="text" size="40" maxlength="40" th:value="*{userName}" th:field="*{userName}" /> <br/> パスワード: <input type="password" size="40" maxlength="40" th:value="*{userPass}" th:field="*{userPass}" /> <br/><br/> <input type="button" value="ログイン" onclick="login();" /> </form> </body> </html> |
さらに、メイン画面のHTMLの内容は以下の通りで、ログアウトボタンが押下されたタイミングで、JavaScriptのlogout関数を呼び出すようになっている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <!DOCTYPE html> <html lang="ja" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <script type="text/javascript" th:src="@{/login.js}"></script> <title>index page</title> </head> <body> <p>ユーザーID、ユーザー名は以下の通りです。</p><br/> <form th:object="${loginForm}"> <span th:text="'ユーザーID: ' + ${uId}">ここにユーザーIDが表示されます</span> <br/> <span th:text="'ユーザー名: ' + ${uName}">ここにユーザー名が表示されます</span> <br/><br/> <input type="button" value="ログアウト" onclick="logout();" /> </form> </body> </html> |
また、JavaScriptの内容は以下の通りで、ログイン・ログアウト処理が含まれている。ログイン処理では、ユーザー情報をHttpヘッダーに設定した後で、コントローラのsetUserSessionメソッド・toMainメソッドを順に呼び出すようになっていて、ログアウト処理では、コントローラのlogoutメソッドを呼び出すようになっている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | 'use strict'; // ログインを行う function login(){ // フォームオブジェクトを取得する let form = document.getElementsByTagName('form')[0]; if(!form){ alert('フォームが取得できませんでした'); return; } // ユーザーID、ユーザー名、パスワードを取得する let userId = ''; let userName = ''; let userPass = ''; const userIdElem = document.getElementById('userId'); if(userIdElem){ userId = userIdElem.value; } const userNameElem = document.getElementById('userName'); if(userNameElem){ userName = userNameElem.value; } const userPassElem = document.getElementById('userPass'); if(userPassElem){ userPass = userPassElem.value; } // XMLHttpRequestオブジェクトを生成し、 // ユーザー情報をHttpヘッダーに設定した後で、 // ユーザー情報をセッションに設定する処理を非同期で呼び出す const xhr = new XMLHttpRequest(); xhr.open('GET', 'setUserSession'); xhr.setRequestHeader('userId', encodeURIComponent(userId)); xhr.setRequestHeader('userName', encodeURIComponent(userName)); xhr.setRequestHeader('userPass', encodeURIComponent(userPass)); xhr.send(null); xhr.onreadystatechange = function() { // ユーザー情報をセッションに設定後 // (非同期通信で結果が返ってきた後に下記if文が実行される) if(xhr.readyState === 4 && xhr.status === 200) { // メイン画面に遷移する form.action = 'toMain'; form.method = 'post'; form.submit(); } } } // ログアウトを行う function logout(){ // フォームオブジェクトを取得する let form = document.getElementsByTagName('form')[0]; if(!form){ alert('フォームが取得できませんでした'); return; } // ユーザー情報をセッションから削除し、ログアウトする form.action = 'logout'; form.method = 'post'; form.submit(); } |
さらに、コントローラクラスの内容は以下の通りで、setUserSessionメソッドでHttpヘッダーからユーザー情報を取得するようになっている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | 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.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; @Controller public class LoginController { /** * Formオブジェクトを初期化して返却する * @return Formオブジェクト */ @ModelAttribute("loginForm") public LoginForm createLoginForm(){ LoginForm loginForm = new LoginForm(); return loginForm; } /** * ログイン画面に遷移する * @return ログイン画面へのパス */ @GetMapping("/") public String toLogin(){ return "login"; } /** * ユーザー情報を取得し、セッションに設定する * @param request HttpServletRequestオブジェクト * @param session HttpSessionオブジェクト * @return ログイン画面へのパス */ @GetMapping("/setUserSession") public String setUserSession(HttpServletRequest request, HttpSession session){ // ユーザーID・ユーザー名・パスワードをHttpヘッダーから取得し、コンソールに出力 String userId = decodeByUTF8(request.getHeader("userId")); String userName = decodeByUTF8(request.getHeader("userName")); String userPass = decodeByUTF8(request.getHeader("userPass")); System.out.println("userId : " + userId + ", userName : " + userName + ", userPass : " + userPass); // ユーザーID・ユーザー名をセッションに設定し、ログイン画面に遷移 session.setAttribute("userId", userId); session.setAttribute("userName", userName); return "login"; } /** * ユーザー情報をセッションから取得し、メイン画面に遷移する * @param session HttpSessionオブジェクト * @param model Modelオブジェクト * @return メイン画面へのパス */ @PostMapping("/toMain") public String toMain(HttpSession session, Model model){ // ユーザーID・ユーザー名をセッションから取得 String userId = (String)session.getAttribute("userId"); String userName = (String)session.getAttribute("userName"); // 取得したユーザーID・ユーザー名をModelオブジェクトに設定し、メイン画面に遷移 model.addAttribute("uId", userId); model.addAttribute("uName", userName); return "main"; } /** * ユーザー情報をセッションから破棄し、ログイン画面に遷移する * @param session HttpSessionオブジェクト * @return ログイン画面へのパス */ @PostMapping("/logout") public String logout(HttpSession session){ // セッションからユーザーID・ユーザー名を破棄し、ログイン画面に遷移 session.removeAttribute("userId"); session.removeAttribute("userName"); return "login"; } /** * 指定された文字列をUTF-8でデコードする * @param str デコード前文字列 * @return デコード後文字列 */ private String decodeByUTF8(String str){ String afterStr = null; try{ afterStr = URLDecoder.decode(str, "UTF-8"); }catch(UnsupportedEncodingException ex){ System.err.println(ex); } return afterStr; } } |
その他、build.gradleの内容は以下の通りで、lombokを利用するための設定が追加されている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | plugins { id 'org.springframework.boot' version '2.1.7.RELEASE' id 'java' } apply plugin: 'io.spring.dependency-management' group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '1.8' repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' //lombokを利用するための設定 compileOnly 'org.projectlombok:lombok:1.18.10' annotationProcessor 'org.projectlombok:lombok:1.18.10' } |
サンプルプログラムの実行結果
サンプルプログラムの実行結果は、以下の通り。
1) Spring Bootアプリケーションを起動し、「http://(サーバー名):(ポート番号)/」とアクセスすると、以下の画面が表示される。
2) ユーザーID、ユーザー名、パスワードを入力し「ログイン」ボタンを押下する。なお、パスワードには「pass」と入力するものとする。
また、コンソールログには、以下の赤枠のように、ユーザーID・ユーザー名・パスワードが出力されていることが確認できる。
4) メイン画面で「ログアウト」ボタンを押下すると、以下のように、ログアウトすることが確認できる。
要点まとめ
- Httpヘッダーに値を設定するには、JavaScript内でXMLHttpRequestオブジェクトを利用すればよい。
- Httpヘッダーから値を取得するには、JavaでHttpServletRequestクラスのgetHeaderメソッドを利用すればよい。