Rainbow Engine

IT技術を分かりやすく簡潔にまとめることによる学習の効率化、また日常の気付きを記録に残すことを目指します。

Java JSP/Servlet

JSP/Servletで画面毎のアクセスカウンターを作成してみた(パート2:ソース解説編)

投稿日:2020年2月2日 更新日:

(1) 仕様について
(2) ソースコード
 (2-1) AccessCounter2.java
  (2-1-1) サンプルPG
  (2-1-2) サンプルPG解説
 (2-2) DbConnectUtil.java
  (2-2-1) サンプルPG
  (2-2-2) サンプルPG解説  (2-3) [画面ID].jsp
  (2-3-1) サンプルPG
  (2-3-2) サンプルPG解説
(3) エラー対応
 (3-1) Java.sql.SQLRecoverableException: Closed Connection

(1) 仕様について

別記事「JSP/Servletで画面毎のアクセスカウンターを作成してみた(パート1:仕様説明編)」をご参照下さい。

目次にもどる

(2) ソースコード

(2-1) AccessCounter2.java

(2-1-1) サンプルPG
package login;
import java.io.IOException;
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 javax.servlet.ServletConfig;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import utility.DbConnectUtil;

@WebServlet("/AccessCounter2")
public class AccessCounter2 extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public void init(ServletConfig config) throws ServletException {
    	super.init(config);
        System.out.println("init() was executed");
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("doGet() was executed");
	}

	public void GetAccessCount2(HttpServletRequest request, HttpServletResponse response, String function) throws ServletException, IOException 
	{
		int access_count=0;
		DbConnectUtil db = new DbConnectUtil();
		Connection conn1 = null;
		Statement stmt1 = null;
		ResultSet rs1 = null; String sql_sel = "SELECT * FROM ACCESS_COUNTER WHERE FUNCTION_ID='"+function+"'";
		ResultSet rs2 = null; String sql_upd ="";
		ResultSet rs3 = null;
		
		conn1 = db.DbConnect(request, response);
		stmt1 = db.DbStatement(request, response, conn1);
		rs1 = db.DbQuery(request, response, stmt1, sql_sel);
		try {
			while(rs1.next()) {
				sql_upd = "UPDATE ACCESS_COUNTER SET ACCESS_COUNT="+(rs1.getInt("ACCESS_COUNT")+1)+" "+
						  "WHERE COUNTER_ID='"+rs1.getString("COUNTER_ID")+"'";	
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		rs2 = db.DbQuery(request, response, stmt1, sql_upd);
		rs3 = db.DbQuery(request, response, stmt1, sql_sel);
		try {
			while(rs3.next()) {
				access_count = rs3.getInt("ACCESS_COUNT");
				System.out.println("accesscount="+access_count+" getInt-ACCESS_COUNT="+rs3.getInt("ACCESS_COUNT"));
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		db.DbClose(request,response,conn1,stmt1,rs1);
		db.DbClose(request,response,conn1,stmt1,rs2);
		db.DbClose(request,response,conn1,stmt1,rs3);
		request.setAttribute(function, access_count);
	}
}

目次にもどる

(2-1-2) サンプルPG解説
行数 処理概要
19行~22行目 特になし
24行~26行目 特になし
28行~64行目 GetAccessCount2メソッドの中で、DB接続やステートメント作成やSQL発行等を行っており、それらを使って指定したアクセスカウンタの値を取得・更新して、更新後の値をセッション内の変数としてセットしています。
30行~40行目 DBアクセスやSQL発行に必要なクラスのインスタンス化や変数の初期化及び1回目のSQL発行(カウンタ取得)を行っています。
・30行目
access_countはアクセスカウンタ用の変数です
・31行目
DbConnectUtilクラスをインスタンス化してDBアクセスに必要なメソッド等を呼べるようにします。
・32行~36行目
Connection型、Statement型、ResultSet型の変数を初期化しています。ResutSetのrs1はカウンタ更新前の値取得用、rs2はUPDATE用、rs3はカウンタ更新後の値取得用です。
・38行~39行目
DbConnectUtilのメソッドを使い、初期化したDB接続系の変数をインスタンス化しています。
・40行目
DbConnectUtilのDbQueryメソッドを用いて、指定した画面の「現在のアクセスカウンタ値」を取得しています。これが次のUPDATE文のWHERE句に使われます。
41行~49行目 ここの区間でアクセスカウンタのUPDATE文を組み立てて、2回目のSQL文の発行(カウンタ更新)を行っています。

・42行~45行目
while(rs1.next())でResultSet(SQL発行の結果)の1行目にカーソルが当てています。「rs1」は指定した画面のアクセスカウンタの情報のため、1行しかない事が自明でUPDATE文もその1行分のみ組み立てられます。
アクセスカウンタのインクリメントは「rs1.getInt(“ACCESS_COUNT”)+1」で行っており、画面の指定はSEQUENCEオブジェクトのカラムを使って「WHERE COUNTER_ID='”rs1.getString(“COUNTER_ID”)”‘」

・49行目
DbQueryメソッドを使ってUPDATE文を発行しています。

50行~62行目 この区間では3回目のSQL発行(カウンタ再取得)とDBオブジェクトのクローズを行っています。

・50行~55行目
while(rs3.next())でResultSet(SQL発行の結果)の1行目にカーソルが当てています。「rs3」は指定した画面のアクセスカウンタの情報のため、1行しかない事が自明。

・59行~61行目
Connection/Statement/ResultSetをクローズしています。これらはメモリの解放漏れやカーソルのクローズ漏れを防ぐためにも明示的にclose処理を行います。

・62行目
取得した「更新後のカウンタ値」を取得します。

目次にもどる

(2-2) DbConnectUtil.java

(2-2-1) サンプルPG

Connectionクラスをインスタンス化する「DbConnect」メソッド、Statementクラスをインスタンス化する「DbStatement」メソッド、SQL発行してResultSetを返却する「DbQuery」等、こちらの記事の「DbConnectTest2」クラスと同等の内容のため、本記事での説明は割愛。
DBアクセス部品のクラスの解説

目次にもどる

(2-2-2) サンプルPG解説

こちらの記事の「DbConnectTest2」クラスと同等の内容のため、本記事での説明は割愛。
DBアクセス部品のクラスの解説 

目次にもどる

(2-3) [画面ID].jsp

(2-3-1) サンプルPG

ユーザーから見える画面JSPのサンプルを紹介します。

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ page import="login.AccessCounter2" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
	<center>
		<h2 id="title">[Screen ID]</h2>
		<h3 id="subtitle">[Name of Screen]</h3>
		<%
		AccessCounter2 ac2 = new AccessCounter2();
		ac2.GetAccessCount2(request, response, "EGDLDNPG");
		%>
		[ Access counter for EGDLDNPG : <b><%=request.getAttribute("EGDLDNPG")%></b> ]
		<br /><br />
	</center>
</head>
<body>
Test
</body>
</html>

 

(図)

目次にもどる

(2-3-2) サンプルPG解説

上記JSPのポイントとなる部分を解説します。

行数 処理概要
11行~14行目 12行目でAccessCounter2クラスをインスタンス化し、13行目でその中のGetAccessCount2メソッドを呼び出しています。ポイントとして、引数に「画面ID」を指定する事により指定した画面のIDをピンポイントで更新します。
15行目 行前半と末尾の『[ Access counter for EGDLDNPG :』と『]』は画面に直接表示するテキストで、その間の『<%=request.getAttribute(“EGDLDNPG”)%>』で指定した画面の「更新後のアクセスカウンタ値」を取得しています。

目次にもどる

(3) エラー対応

(3-1) Java.sql.SQLRecoverableException: Closed Connection

このエラーが発生した際の対応については、下記の記事にて解説しているため割愛。
Java.sql.SQLRecoverableException: Closed Connectionの対応 

目次にもどる

Adsense審査用広告コード


Adsense審査用広告コード


-Java, JSP/Servlet

執筆者:


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

関連記事

JFreeChartの折れ線グラフ(LineChart)をより綺麗に見せるための11個のテクニック

(0)目次&概説 (1) 記事の目的 (2) LineChartの表示改善  (2-1)【線】線の太さを変更  (2-2)【線】各シリーズ(Series)毎に折れ線の色を設定  (2-3)【線】各シリ …

Javaのabstractとは?抽象クラスの概要やサンプルPGをご紹介

<目次> (1) Javaのabstractとは?抽象クラスの概要やサンプルPGをご紹介  (1-1) 抽象クラス(abstract)とは  (1-2) 抽象クラスの目的や用途  (1-3) 抽象クラ …

Javaでカンマやクォーテーションをエスケープする方法

<目次> (1) Javaでカンマやクォーテーションをエスケープする方法  (1-1) 実現方法・構文  (1-2) サンプルプログラム  (1-3) 参考:カンマとダブルクォーテーション両方のエスケ …

JSP Servletで共通のヘッダーを設定する方法

<目次> (1) JSP Servletで共通のヘッダーを設定する方法  (1-1) 構文  (1-2) サンプルプログラム  (1-3) 参考 (1) JSP Servletで共通のヘッダーを設定す …

JavaのhashCode()で31を掛け算する理由について

<目次> (1) JavaのhashCode()で31を掛け算する理由について  (1-1) ハッシュの計算のソースコード  (1-2) ソースコードに登場する代表的な変数  (1-3) ソースコード …

  • English (United States)
  • 日本語
Top