【Java】アプリケーションスコープ:good評価とbad評価を加算していく

■スコープ

サーブレットクラスで作成したインスタンスをJSPファイルで利用するために、スコープを使用する。
スコープとは、インスタンスを保存する領域であり、サーブレットクラス・JSPファイル共にインスタンスの保存・保存したインスタンスの取得をすることができる。

スコープのざっくりイメージ図

▼スコープの種類

スコープは、以下、4つの種類がある。


・ページスコープ

・リクエストスコープ

・セッションスコープ

・アプリケーションスコープ

※保存したインスタンスの有効期限の長さが異なる。

▼スコープのお約束

スコープに保存できるのはあくまでインスタンスのみである。

int型やString型などのデータ型の変数を保存することはできない。

データ型の変数を保存したい場合は、ラッパークラス(データ型のみを保持するクラス)を作成し、そのラッパークラスをインスタンス→保存する。

▼JavaBeans

スコープには、JavaBeansと呼ぶクラスのインスタンスを保存することが多い。

JavaBeans(※現場によってはBeanと呼ぶこともある)とは、クラスの独立性を高め、部品として再利用するために、以下のルールがある。


①直列可能(java.io.Serializableをimportし、クラスに対してインターフェースしている)

②クラスはpublic

③publocで引数のないコンストラクタを持つ

④フィールドはprivate

⑤取得、保存はゲッター/セッターを使用する。

■アプリケーションスコープ

アプリケーションスコープにおいて、保存したインスタンスは、開発者が明示的に削除するか、アプリケーションが終了(サーバの起動と終了)するまで使用可能である。

すなわち、アプリケーションスコープはブラウザを閉じても、値は保持され、別のユーザが使用しても、同じ情報を使用することができる。

■作成するプログラムの概要

フォーム画面にて「good」と「bad」を選択する。
選択した結果をサーブレットにて加算する。
累計の「good」数と「bad」数を表示する。

■フローチャート

■プログラム仕様

・サーブレットクラス(GoodBadCounter.java)

(1)POST処理

インプット処理内容アウトプット
【フォーム情報】
good
bad
【フォーム情報】を取得する。
アプリケーションスコープをインスタンス。
アプリケーションスコープのgood/bad情報をインスタンス。
【条件分岐】
アプリケーションスコープのgood/bad情報
▼Nullの場合
Beansクラス(GoodBadBeans)を初期化する。
▼それ以外
何もしない。
【条件分岐】
【フォーム情報】の値
▼0の場合
goodを加算する。
▼1の場合
badを加算する。
アプリケーションスコープにgood/bad情報を保存する。
【URL】
*1
JSPファイルへ画面遷移する。

*1:URL(/WEB-INF/jsp/good_bad_count.jsp)

(2)GET処理

インプット処理内容アウトプット
【URL】
*1
JSPファイルへ画面遷移する。

*1:URL(/WEB-INF/jsp/good_bad_count.jsp)


・JSPファイル(good_bad_count.jsp)

インプット処理内容アウトプット
アプリケーションスコープのgood/bad情報をインスタンス。
【条件分岐】
▼good/bad情報がNullの場合
good件数:0件を表示する。・・・①
bad件数:0件を表示する。
▼good/bad情報がある場合
good/badの件数を表示する。・・・②
【画面】
①good/bad:0件
②good/badの件数

■画面仕様

①入力フォームを作成する。
・goodもしくはbadをラジオボタンで選択する。
・デフォルトでgoodのラジオボタンにチェックを入れる。
・「登録」ボタン押下時にサーブレット処理を実行する。

②Good/Bad情報を表示する。

■サンプルコード

・サーブレットクラス(GoodBadCounter.java)

package servlet;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import beans.GoodBadBeans;

@WebServlet("/GoodBadCounter")
public class GoodBadCounter extends HttpServlet {
	private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	// 画面へ遷移(Getの場合は何もしない)
    	RequestDispatcher rd = request.getRequestDispatcher("/WEB-INF/jsp/good_bad_count.jsp");
    	rd.forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// Jspのフォーム画面からgood/bad情報を取得
		request.setCharacterEncoding("UTF-8");
		String input_good_bad = request.getParameter("radiobtn_good_bad");
		
		// アプリケーションスコープをインスタンス
		ServletContext appscope = this.getServletContext();
		
		// 既存のgood/bad情報を取得する
		GoodBadBeans good_bad = (GoodBadBeans)appscope.getAttribute("good_bad"); 
		
		// アプリケーションスコープ情報がない場合は、新規作成(初回のみ)
		if(good_bad == null) {
			// Beansクラスを初期化
			 good_bad = new GoodBadBeans();
		} 
		
		// カウント用の一時変数
		int count = 0;
			
		// good/bad判定(0:goodに+1する、1:badに+1する、以外:何もしない)
		if(input_good_bad.equals("0")) {
			count = good_bad.getGood_count();
			good_bad.setGood_count(count + 1);
		} else if(input_good_bad.equals("1")){
			count = good_bad.getBad_count();
			good_bad.setBad_count(count + 1);
		}
		
		// アプリケーションスコープに保存
		appscope.setAttribute("good_bad", good_bad);
			
		// 画面へ遷移
    	RequestDispatcher rd = request.getRequestDispatcher("/WEB-INF/jsp/good_bad_count.jsp");
    	rd.forward(request, response);
	}

}

・Beansクラス(GoodBadBeans.java)

package beans;

import java.io.Serializable;

public class GoodBadBeans implements Serializable{
	// フィールドの設定
	private int good_count;
	private int bad_count;
	
	// [good]のゲッターとセッターを設定
	public int getGood_count() {
		return good_count;
	}
	public void setGood_count(int good) {
		this.good_count = good;
	}
	
	// [bad]のゲッターとセッターを設定
	public int getBad_count() {
		return bad_count;
	}
	public void setBad_count(int bad) {
		this.bad_count = bad;
	}
	
	// コンストラクタ(設定なし)
	public GoodBadBeans() {
		
	}
}

・JSPファイル(good_bad_count.jsp)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%@ page import="beans.GoodBadBeans" %>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Good/Bad</title>
</head>
<body>

<!-- 登録情報入力 -->
<form action="http://localhost:8080/JspServletSample/GoodBadCounter" method="post">
	<p>
		Good:<input type="radio" name="radiobtn_good_bad" value="0" checked>
		<br>
		Bad:<input type="radio" name="radiobtn_good_bad" value="1">
		<br>
	</p>
	<input type="submit" value="登録">
</form>

<!-- アプリケーションスコープ取得情報(取得できた場合のみ表示) -->
<p>#################### Good/Bad情報 ####################</p>
<!-- アプリケーションスコープの呼びだし -->
<% 
	GoodBadBeans good_bad = (GoodBadBeans)application.getAttribute("good_bad"); 
	if(good_bad == null){
%>
		<p>
			Good:0件
			<br>
			Bad:0件
		</p>
<%
	} else {
%>
		<p>
			Good:<%=good_bad.getGood_count() %>件
			<br>
			Bad:<%=good_bad.getBad_count() %>件
		</p>
<%
	}
%>

</body>
</html>

■実行結果

・初回起動時(Webブラウザ:Chrome)


・「登録」ボタン押下時(「Good」を選択)

Goodの件数が1増える。


・Good/Badを選択し任意の回数「登録」ボタンを押下(追加でGood:7回、Bad:4回)

それぞれの件数が加算されていく。


・サーバ再起動せず、Safariで起動

違うブラウザでも同じ件数が表示される。


・サーバ再起動

「Chrome」、「Safari」ともに、件数は0に戻る。