[JSP]Servlet網站人數圖形計數器

計數器可以計算有多少人來瀏覽網頁,主要是利用java Servlet來產生圖形串流,輸出至使用者端,一般的capatch也可以使用此原理來製做。

程式可利用參數的傳遞來改變計數器的樣式,像是背景、前景、字型大小、字型顏色,還可以指定要存放的檔案名稱來區分想要計數的網頁,大概的結果樣式如下:

左邊是有更改Session及存取檔案名稱,右邊是預設的,二個可以同時執行各自計算數量

參數是cname=檔案名稱,sname=Session參數

結果.png

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

CountTxt.png




其它參數可以參考範例的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

CreateServlet.png

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

CreateServlet2.png

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

CreateServlet3.png

以下是此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;

    }

}

原始碼下載

發表迴響