計數器可以計算有多少人來瀏覽網頁,主要是利用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; } }