HTTPは、Webサーバーとクライアント(ブラウザ)の間で、ウェブページを送受信するためのプロトコルで、以下のページに示すように、HTTPメッセージはヘッダーとボディを含んでいる。
http://www.tohoho-web.com/ex/http.htm
今回は、HTTPボディでなくHTTPヘッダーに値を設定し取得するサンプルプログラムを作成してみたので、共有する。
前提条件
下記記事の実装が完了していること。
サンプルプログラムの作成
作成したサンプルプログラムの構成は以下の通り。

なお、上記の赤枠は、前提条件のプログラムから追加/変更したプログラムである。
まず、ログインFormの内容は以下の通りで、ユーザーID・ユーザー名・パスワードをもっている。
package com.example.demo;
import lombok.Data;
@Data
public class LoginForm {
/** ユーザーID */
private String userId;
/** ユーザー名 */
private String userName;
/** パスワード */
private String userPass;
}
次に、ログイン画面のHTMLの内容は以下の通りで、ログインボタンが押下されたタイミングで、JavaScriptのlogin関数を呼び出すようになっている。
<!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関数を呼び出すようになっている。
<!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メソッドを呼び出すようになっている。
'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ヘッダーからユーザー情報を取得するようになっている。
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を利用するための設定が追加されている。
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メソッドを利用すればよい。






