計數器可以計算有多少人來瀏覽網頁,主要是利用java Servlet來產生圖形串流,輸出至使用者端,一般的capatch也可以使用此原理來製做。
程式可利用參數的傳遞來改變計數器的樣式,像是背景、前景、字型大小、字型顏色,還可以指定要存放的檔案名稱來區分想要計數的網頁,大概的結果樣式如下:
左邊是有更改Session及存取檔案名稱,右邊是預設的,二個可以同時執行各自計算數量
參數是cname=檔案名稱,sname=Session參數

可以看到檔案被自動建立了

其它參數可以參考範例的html code
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>使用預設的檔案做計數器檔案</title>
</head>
<body>
檔案名稱為:count.txt SessionName:count
<table style="border: 1px solid #000000">
<tr>
<td>原始</td>
<td>前景rgb(255,255,255)<br />
背景rgb(121,82,205)<br />
字型Size 24<br />
字型 Courier</td>
<td><img src="Counter.jpg" /></td>
</tr>
<tr>
<td>更改前景</td>
<td>前景rgb(15,185,15)<br />
背景rgb(121,82,205)<br />
字型Size 24<br />
字型 Courier</td>
<td><img src="Counter.jpg?fr=15&fg=185&fb=15" /></td>
</tr>
<tr>
<td>更改背景</td>
<td>前景rgb(255,255,255)<br />
背景rgb(0,255,255)<br />
字型Size 24<br />
字型 Courier</td>
<td><img src="Counter.jpg?bgr=0&bgg=255&bgb=255" /></td>
</tr>
<tr>
<td>更改字型Size</td>
<td>前景rgb(255,255,255)<br />
背景rgb(121,82,205)<br />
字型Size 18<br />
字型 Courier</td>
<td><img src="Counter.jpg?size=18" /></td>
</tr>
<tr>
<td>更改字型</td>
<td>前景rgb(255,255,255)<br />
背景rgb(121,82,205)<br />
字型Size 24<br />
字型 Arial</td>
<td><img src="Counter.jpg?f=Arial" /></td>
</tr>
</table>
</body>
</html>
index2.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>使用count2.txt做計數器檔案</title>
</head>
<body>
檔案名稱為:count2.txt SessionName:count2
<table style="border: 1px solid #000000">
<tr>
<td>原始</td>
<td>前景rgb(255,255,255)<br />
背景rgb(121,82,205)<br />
字型Size 24<br />
字型 Courier</td>
<td><img src="Counter.jpg?cname=count2.txt&sname=count2" /></td>
</tr>
<tr>
<td>更改前景</td>
<td>前景rgb(15,185,15)<br />
背景rgb(121,82,205)<br />
字型Size 24<br />
字型 Courier</td>
<td><img
src="Counter.jpg?fr=15&fg=185&fb=15&cname=count2.txt&sname=count2" /></td>
</tr>
<tr>
<td>更改背景</td>
<td>前景rgb(255,255,255)<br />
背景rgb(0,255,255)<br />
字型Size 24<br />
字型 Courier</td>
<td><img
src="Counter.jpg?bgr=0&bgg=255&bgb=255&cname=count2.txt&sname=count2" /></td>
</tr>
<tr>
<td>更改字型Size</td>
<td>前景rgb(255,255,255)<br />
背景rgb(121,82,205)<br />
字型Size 18<br />
字型 Courier</td>
<td><img src="Counter.jpg?size=18&cname=count2.txt&sname=count2" /></td>
</tr>
<tr>
<td>更改字型</td>
<td>前景rgb(255,255,255)<br />
背景rgb(121,82,205)<br />
字型Size 24<br />
字型 Arial</td>
<td><img src="Counter.jpg?f=Arial&cname=count2.txt&sname=count2" /></td>
</tr>
</table>
</body>
</html>
在Eclipse如何建立Servlet
可以參考以下步驟在src目錄下按右鍵選new –> Other –> Servlet
然後在Create Servlet視窗裡輸入java的package及Class name

再來設定URL mapping的網址,以此範例則可在網址上輸入http://servername:port/Counter.jpg 來執行這個Servlet

然後選擇要建立的方法有那些,主要是doPost及doGet

以下是此Servlet的原始碼:
Counter.java
package yslifes.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.awt.image.*;
import java.awt.Font;
import javax.imageio.*;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.FontMetrics;
/**
* Servlet implementation class Counter
*/
public class Counter extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public Counter() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
int bgr, bgg, bgb, size, fr, fg, fb;
String count_name = null;
String session_name = null;
String f;
//背景的rgb
String rbgr = (String) request.getParameter("bgr");
String rbgg = (String) request.getParameter("bgg");
String rbgb = (String) request.getParameter("bgb");
//字型大小
String rsize = (String) request.getParameter("size");
//前景的rgb
String rfr = (String) request.getParameter("fr");
String rfg = (String) request.getParameter("fg");
String rfb = (String) request.getParameter("fb");
//字型
String rf = (String) request.getParameter("f");
//要存放的的檔案名稱,可以來區別不同來源的計數器
String countName = (String) request.getParameter("cname");
//session Name
String sessionName = (String) request.getParameter("sname");
//預設值
if (rbgr == null || rbgr.equals(""))
bgr = 121;
else
bgr = Integer.parseInt(rbgr);
if (rbgg == null || rbgg.equals(""))
bgg = 82;
else
bgg = Integer.parseInt(rbgg);
if (rbgb == null || rbgb.equals(""))
bgb = 205;
else
bgb = Integer.parseInt(rbgb);
if (rsize == null || rsize.equals(""))
size = 24;
else
size = Integer.parseInt(rsize);
if (rfr == null || rfr.equals(""))
fr = 255;
else
fr = Integer.parseInt(rfr);
if (rfg == null || rfg.equals(""))
fg = 255;
else
fg = Integer.parseInt(rfg);
if (rfb == null || rfb.equals(""))
fb = 255;
else
fb = Integer.parseInt(rfb);
if (rf == null || rf.equals(""))
f = "Courier";
else
f = (rf);
if (countName == null || countName.equals(""))
count_name = new String("count.txt");
else
count_name = new String(countName);
if (sessionName == null || sessionName.equals(""))
session_name = new String("count");
else
session_name = new String(sessionName);
response.setContentType("image/jpeg");
HttpSession session = request.getSession(true);
String url = this.getServletContext().getRealPath("/");
System.out.println(url);
if (!session.isNew()) // 如果有session
{
// 設定session 三十分鐘重新reload
Date halfAgo = new Date(
(long) (System.currentTimeMillis() - 0.5 * 60 * 60 * 1000));
Date create = new Date(session.getLastAccessedTime());
if (create.before(halfAgo)) {
session.invalidate();
session = request.getSession(true);
}
}
Integer count = (Integer) (session.getAttribute("tracker."
+ session_name));
// 取得session的值
if (count == null) {
count = new Integer(got_count(url, count_name));
// 讀取檔案內count數
}
session.setAttribute("tracker." + session_name, (Object) (count));
// 設定session值
String str = new String(
(session.getAttribute("tracker." + session_name)).toString());
BufferedImage outimg = out_image(
url,
new String("0000000" + str).substring(
("0000000" + str).length() - 7,
("0000000" + str).length()), bgr, bgg, bgb, size, f,
fr, fg, fb);
ServletOutputStream sos = response.getOutputStream();
ImageIO.write(outimg, "PNG", sos);
sos.close();
response.flushBuffer();
// res.getWriter().write(new
// String("0000000"+str).substring(("0000000"+str).length()-7,("0000000"+str).length()));
}
private int got_count(String url, String count_name)// 重新取得count數
{
// System.out.println(url);
File f = new File(url, count_name);
// 讀取檔案
String str = "0";
try {
if (f.exists() == false) {
f.createNewFile();
FileWriter fo = new FileWriter(f);
fo.write("0".toString());
fo.close();
// 不存在則建立,設定0為初值
}
FileReader fi = new FileReader(f);
StringBuffer sb = new StringBuffer("");
int ch = 0;
while ((ch = fi.read()) != -1) {
sb.append((char) (ch));
}
// 讀取內容值
fi.close();
f = null;
str = new String(
String.valueOf(Integer.parseInt(sb.toString()) + 1));
// 取得內容值加一
FileWriter fw = new FileWriter(url + count_name);
fw.write(str);
// 回寫
fw.close();
f = null;
} catch (Exception e) {
System.out.println(e.toString());
}
return Integer.parseInt(str.toString());
}
private BufferedImage out_image(String url, String count, int bgr, int bgg,
int bgb, int size, String f, int fr, int fg, int fb) {
Font font = new Font(f, Font.BOLD, size);
// 設定count的字型
Color bg = new Color(bgr, bgg, bgb);
// 背景色
Color fontcolor = new Color(fr, fg, fb);
// 字體顏色
FontMetrics fm;
// Font套件,可取得size高及寬
int width = 16 * 7, height = 21;
// 初始out_image長及寬
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
g.setColor(bg);
g.fillRect(0, 0, width, height);
g.setFont(font);
fm = g.getFontMetrics(font);
g.setColor(fontcolor);
g.drawString(count, (width - fm.stringWidth(count)) / 2,
(0 + fm.getHeight()) / 2);
return image;
}
}