読者です 読者をやめる 読者になる 読者になる

感謝のプログラミング 10000時間

たどり着いた結果(さき)は、感謝でした。

JSPとサーブレットでアクセスカウンタもどきを作ってみた

<スポンサーリンク>

JSPでサーブレットにリクエストを飛ばす。
リクエストを受け取ったサーブレットは、そのリクエストのたびに、リクエストをカウントしていく。カウントアップした値を持つのはJavaBeanである。
そして、カウントアップされた値を持つJavaBeanをJSPが読み込む。

サーブレットの値をJSPが読み込むって感じか。
そんなサンプルを作った。
サーブレットの値をJSPで表示させたかったので。。
突貫工事で作ったけど、全然不完全なので、もしブログを見てくれる方がいたとしてもあまり真似しないでください。。。

まずは、サーブレット側。
アクセス数を保持するJavaBeanはこんな感じ

package counter;

public class AccessCounter {
	private static int count;
	private byte[] lock = new byte[0];
	
	public AccessCounter(){}
	
	public int getCount() {
		synchronized(lock) {
			return count;
		}
	}
	
	public int increment() {
		synchronized(lock) {
			count += 1;
			return count;
		}
	}
	
	public void setCount(int val) {
		synchronized(lock) {
			count = val;
		}
	}
}

こいつがリクエストされた数を保持するクラス。

それで次に、GETリクエストを受け取って、アクセスカウンタをインクリメントするサーブレット。
アクセスカウンタをインクリメントしたあとに、JSPに処理を戻しているのがrequestDispatcherの部分。forwardしている。

package counter;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CounterServlet extends HttpServlet {
	
	private int count;
	AccessCounter ac;
	CountFile cf;
	
	public void init(ServletConfig conf) throws ServletException {
		super.init(conf);
		cf = new CountFile("C:\\temp\\count.txt");
		try {
			count = cf.getInitCount();
		} catch(IOException e) {
			count = 0;
		}
		ac = new AccessCounter();
		ac.setCount(count);
	}
	
	public void doGet(HttpServletRequest request,
						HttpServletResponse response) 
						throws IOException, ServletException {
		count = ac.increment();
		System.out.println(count);
		RequestDispatcher dispatcher = request.getRequestDispatcher("/request.jsp");
		dispatcher.forward(request, response);
	}
	
	public void destroy() {
		try {
			//閉じる直前にファイルサーバにアクセス数を書き込む
			System.out.println("destroy!!");
			cf.setInitCount(count);
		} catch (IOException ignore) {
			
		} finally {
			cf = null;
		}
		ac = null;
		super.destroy();
	}

}
||
一応閉じる直前にファイルに永続化する処理を入れた。
なんちゃって永続化を担当するのが以下のクラス。
>|java|
package counter;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CountFile {
	private String filename = "count.txt";
	private byte[] lock = new byte[0];
	private int initCount = 0;
	
	public CountFile(){}
	
	public CountFile(String filepath) {
		if (filepath != null && filepath.length() != 0 ) {
			filename = filepath;
		}
	}
	
	public int getInitCount() throws IOException {
		String line = "";
		FileReader freader = null;
		BufferedReader breader = null;
		synchronized(lock) {
			freader = new FileReader(filename);
			breader = new BufferedReader(freader);
			line = breader.readLine();
			if (line != null || line.length() != 0) {
				initCount = Integer.parseInt(line);
			}
			freader.close();
			breader.close();
			return initCount;	
		}
	}
	
	public void setInitCount(int count) throws IOException {
		FileWriter fwriter = null;
		synchronized(lock) {
			initCount = count;
			System.out.println(filename+"に"+count+"を書き込みます");
			fwriter = new FileWriter(filename);
			fwriter.write(Integer.toString(count));
			fwriter.close();
		}
	}
}

ファイルにカウント数を書き出す役割を果たす。

それで、サーブレットにリクエストを飛ばすJSP。
中でJavaBeanであるAccessCounterの値を取得して、表示している。

<%@page contentType="text/html; charset=Windows-31J"%>
<%@page import="counter.AccessCounter" %>
<jsp:useBean id="counter" class="counter.AccessCounter" scope="application" />
<html>
<head>
<title>JSPとサーブレットでアクセスカウンタを作ってみる</title>
</head>
<body>
<h2>Beansを使ったアクセスカウンタ</h2>
<table border="1">
  <tr bgcolor="yellow">
     <td align="center"><b>ボタン</b></td>
     <td align="center"><b>アクセス数</b></td>
  </tr>
  <tr>
    <td align="center"><form action="/webtest/counter.CounterServlet" method="GET">
        <input type="submit" value="カウントアップ!">
    </form>
    </td>
    <td align="center"><jsp:getProperty name="counter"
    property="count" /></td>
  </tr>
</table>
</body>
</html>

これらのweb.xmlはこんな感じ

<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
 Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   version="2.5">
   

  <display-name>Welcome to Tomcat</display-name>
  <description>
     Welcome to Tomcat
  </description>
    <servlet>
     <servlet-name>AccessCounter</servlet-name>
     <servlet-class>counter.CounterServlet</servlet-class>
  </servlet>
  <servlet-mapping>
     <servlet-name>AccessCounter</servlet-name>
     <url-pattern>/counter.CounterServlet</url-pattern>
  </servlet-mapping>

</web-app>

で、ブラウザはこうなる
http://localhost:8082/webtest/request.jsp
で、

カウントアップ!ボタンを押すたびに値がインクリメントされていく。


参考にしたのは以下の書籍。
古くても優秀な本である。300円で買えるし。

サーブレット/JSP プログラミングテクニック

サーブレット/JSP プログラミングテクニック

改版が出ていたので、買いたい。

サーブレット/JSP プログラミングテクニック 改訂版

サーブレット/JSP プログラミングテクニック 改訂版

  • 作者: 今野睦,戸田和宏,藤村浩士,高安厚思,西川麗,三島俊司
  • 出版社/メーカー: ソフトバンククリエイティブ
  • 発売日: 2003/09/30
  • メディア: 単行本
  • クリック: 2回
  • この商品を含むブログ (4件) を見る

基礎からのサーブレット/JSP 第3版 (基礎からのシリーズ)

基礎からのサーブレット/JSP 第3版 (基礎からのシリーズ)