明輝手游網(wǎng)中心:是一個免費提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺!

用Java Servlet構(gòu)建旗幟廣告系統(tǒng)

[摘要]對于一個商務(wù)網(wǎng)站來說,廣告系統(tǒng)是必不可少的。一個好的廣告系統(tǒng)是一個網(wǎng)站穩(wěn)定收入的基礎(chǔ)。而旗幟廣告(banner)則是網(wǎng)站廣告中占絕大部分的廣告,因此開發(fā)一個旗幟廣告系統(tǒng)就非常重要了。利用Java Servlet 我們可以很輕松的構(gòu)建屬于我們自己的旗幟廣告系統(tǒng)。   我們一般在網(wǎng)頁上放上一些圖片,...
對于一個商務(wù)網(wǎng)站來說,廣告系統(tǒng)是必不可少的。一個好的廣告系統(tǒng)是一個網(wǎng)站穩(wěn)定收入的基礎(chǔ)。而旗幟廣告(banner)則是網(wǎng)站廣告中占絕大部分的廣告,因此開發(fā)一個旗幟廣告系統(tǒng)就非常重要了。利用Java Servlet 我們可以很輕松的構(gòu)建屬于我們自己的旗幟廣告系統(tǒng)。  

  我們一般在網(wǎng)頁上放上一些圖片,設(shè)置它們的鏈接指向廣告客戶的網(wǎng)頁,然后產(chǎn)生日志文件存放瀏覽的人數(shù),瀏覽者的IP等信息,這就是開發(fā)旗幟廣告系統(tǒng)的一般思路。  
下面,我想結(jié)合一個例程來介紹一下如何使用Java Servlet來構(gòu)建旗幟廣告系統(tǒng)。這下面這個例子中,你必須使用在你的HTML文件中使用<IMG> 標(biāo)簽。  
用法有三種是:  

  1) Banner?config_file 或Banner?config=config_file  

  例如:  

  。糏MG height=125 src="http://localhost/servlet/Banner?config_file" width=125>  

用這種方法你就可以顯示不同的圖片了。  

  2) 你也可以為每一幅圖片設(shè)置自己的重定向URL。只需在你的設(shè)置中添加文件描述,見下面的例子,Servlet也需要更多的描述參數(shù):  

     

   <IMG height=60 src="http://localhost/servlet/Banner?config=config_file&mode=1" width=468>  

這樣你就可以支持標(biāo)準(zhǔn)的旗幟廣告了。  

  3)你也可以在同一個頁面上有多個旗幟廣告。你只需要在參數(shù)中加入“id=某個整數(shù)值”就可以了。這個值必須是一個你的頁面內(nèi)唯一的整數(shù)值!例如,對于第一個banner的描述為:  

     

   <IMG height=60 src="http://localhost/servlet/Banner?config=config_file&mode=1&id=1" width=468>  

  第二個為:  

     

   <IMG height=125 src="http://localhost/servlet/Banner?config=config_file&mode=1&id=2" width=125>  

有的朋友會問了,config_file是什么文件呀? 它是一個文本文件,用來描述Servlet的設(shè)置信息。你能在你的主機的任何地方保存這個文件,F(xiàn)把參數(shù)介紹一下,這個配置文件有三個參數(shù):分別為  

  1、dir=some_directory

  解釋: dir是你的旗幟廣告文件存放的目錄,可以使用的圖片格式有JPG ,GIF,PNG ,JPEG等。這個參數(shù)是必須有的,否則系統(tǒng)會報錯。

  2、bannerfilename=some_url  

  解釋: banner文件使用下面的格式,例如:  

   banner.gif=http://www.yesky.com/  

   banner.jpg=http://www.yesky.com/  

  3、log=some_directory_to_store_log_file

  解釋:存放日志文件的目錄,可以是服務(wù)器上的任何目錄。
  附錄1、日志文件(log file)及格式  

  Banner 系統(tǒng)每天會自動產(chǎn)生兩個日志文件。分別為ddmmyyyyv.txt和ddmmyyyyc.txt 。第一個文件保存瀏覽banner的記錄,第二個文件保存重定向的記錄。兩個文件都是文本文件,每一行包括一條記錄。紀(jì)錄格式是:  

  IP地址 日期 圖片文件 用戶代理 重定向記錄 (只用于 *c.txt文件) ,字段之間用空格隔開。  


附錄2、Banner.java源程序:  

  import java.io.*;  

  import java.util.*;  

  import javax.servlet.*;  

  import javax.servlet.http.*;  

  public class Banner extends HttpServlet  

   {  

    public Banner(){ }  

    //讀取配置文件內(nèi)容  

    private boolean readConfig(String sConfig, Hashtable hashtable)  

    {  

     try  

      {  

       BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(new FileInputStream(sConfig)));// 設(shè)置緩沖區(qū)讀入一個配置文件  

       String sLineInformation1;//  

       while((sLineInformation1 = bufferedreader.readLine()) != null)  

       {  

        sLineInformation1 = sLineInformation1.trim();//去除字符串中的空格  

        if(sLineInformation1.length() > 0)//如果字符串sLineInformation1的長度大于零 {  

         int i = sLineInformation1.indexOf("=");  

         if(i > 0 && i < sLineInformation1.length() - 1 && sLineInformation1.charAt(0) != "#" && !sLineInformation1.startsWith("//"))//配置文件的每一行參數(shù)必須以不為#或//開頭的字符串

          hashtable.put(sLineInformation1.substring(0, i).trim().toLowerCase(), sLineInformation1.substring(i + 1).trim());

          }

         }

        bufferedreader.close();

        File file = new File(sConfig);//創(chuàng)建一個配置文件

        hashtable.put("edited", String.valueOf(file.lastModified()));

        }

       catch(Exception _ex)

       {

        return false;

       }

      String sDirInfo2 = (String)hashtable.get("dir");//取得目錄參數(shù)

      if(sDirInfo2 != null)//如果目錄參數(shù)是空值

       {

        if(!sDirInfo2.endsWith(separator))//如果sDirInfo2不是以分隔符結(jié)尾,那么

        {

         sDirInfo2 = sDirInfo2 + separator;//給sDirInfo2加上分隔符

         hashtable.remove("dir");//移去哈希表變量中的dir

         hashtable.put("dir", sDirInfo2);

        }

      File file1 = new File(sDirInfo2);

      String as[] = file1.list();

      if(as == null) {

       hashtable.remove("dir");

       }

      sDirInfo2 = (String)hashtable.get("log");

      if(sDirInfo2 != null)

       {

        if(!sDirInfo2.endsWith(separator))

         {

          sDirInfo2 = sDirInfo2 + separator;

          hashtable.remove("log");

          hashtable.put("log", sDirInfo2);

         }

      File file2 = new File(sDirInfo2);

      String as1[] = file2.list();

      if(as1 == null) {

       hashtable.remove("log");

       }

      return true;

     }

    private Hashtable getConfig(String s)//取得配置

     {

      Hashtable hashtable = (Hashtable)cfgs.get(s);

      if(hashtable != null)//如果配置不為空

      try

       {

        String s1 = (String)hashtable.get("edited");

        File file = new File(s);

        if(!s1.equals(String.valueOf(file.lastModified()))){

        //如果s1的值不等于文件最后一次修改的值,則hashtable的內(nèi)容為空值

         hashtable = null;

         }

        catch(Exception _ex)//捕獲Exception _ex錯誤

         {

          hashtable = null;

         }

        if(hashtable != null)

         return hashtable;

         hashtable = new Hashtable();

        if(!readConfig(s, hashtable))

         {

          return null;

         }

        else

         {

          cfgs.put(s, hashtable);

          return hashtable;

         }

        }


     public void init(ServletConfig servletconfig)//初始化配置參數(shù)

      throws ServletException {

        //如果出錯,拋出一個ServletException錯誤

         super.init(servletconfig);

         separator = System.getProperty("file.separator");//取得分隔符

         cfgs = new Hashtable();//設(shè)置配置變量

         logs = new Hashtable();//設(shè)置日志變量

         System.out.println("? Wayne Zheng ");//屏幕輸出我的郵箱地址

        }


     public void destroy()

     {

      }


     public void doPost(HttpServletRequest request, HttpServletResponse response)

            //發(fā)送POST請求

      throws ServletException, IOException

       { doGet(request, response); }

      public void doGet(HttpServletRequest httpservletrequest, HttpServletResponse httpservletresponse) //讀取GET

      throws ServletException, IOException

      {

       String strConfig = httpservletrequest.getQueryString();

       //讀取請求字符串

       if(strConfig == null)//如果字符串為空

        strConfig = "";//那么設(shè)置strConfig為空

        if(strConfig.length() == 0)

        //如果strConfig長度為零,那么顯示錯誤信息

        {

         errorMessage("無配置信息!", httpservletresponse);

         return;

        }

        String strConfig1 = getFromQuery(s, "config=");//同上

        if(strConfig1.length() == 0){

         strConfig1 = strConfig;

         Hashtable hashtable = getConfig(strConfig1);

         if(hashtable == null)

         {

           errorMessage("配置信息錯誤!", httpservletresponse);

           return;

         }

         if(hashtable.get("dir") == null)

         //如果哈希表中dir為空值,則輸出錯誤信息

         {

          errorMessage("不能打開數(shù)據(jù)目錄", httpservletresponse);

          return;

         }

       String strConfigMode2 = getFromQuery(strConfig, "mode=");//讀取配置中的mode值

       if(strConfigMode2.length() == 0){//如果沒有mode值

        strConfigMode2 = "1";//則設(shè)mode值為1

        String strConfigId3 = getFromQuery(strConfig, "id=");//讀取配置中的id值

        if(strConfigId3.length() == 0){ file://如果沒有id值

          strConfigId3 = "1";//則設(shè)id值為1

          HttpSession httpsession = httpservletrequest.getSession(true);

          if(strConfigMode2.equals("1"))

          file://如果strConfigMode2的值為1,則顯示banner廣告

          {

           showBanner(hashtable, strConfigId3, httpsession, httpservletrequest, httpservletresponse);

           return;

           }


else //否則轉(zhuǎn)向banner所指的站點  

           {  

            goToSite(hashtable, strConfigId3, httpsession, httpservletrequest, httpservletresponse);  

            return;  

           }  

         }  

       private void goToSite(Hashtable hashtable, String s, HttpSession httpsession, HttpServletRequest httpservletrequest, HttpServletResponse httpservletresponse)//轉(zhuǎn)向站點  

        throws IOException //如果有任何錯誤,拋出IOException錯誤  

        {  

         String sitename1;//定義站點名  

         if(httpsession == null)//如果httpsession為空  

          {  

           sitename1 = getFirstSite(hashtable);//站點名為哈希表中的第一個站點名  

           }  

         else //否則  

          {  

           Hashtable hashtable1 = (Hashtable)httpsession.getValue("旗幟廣告系統(tǒng) ,Wayne Zheng");  

         if(hashtable1 == null){ //如果哈希表hashtable1為空值,則  

           sitename1 = getFirstSite(hashtable);// 站點名為哈希表(hashtable)中的第一個站點名  

         else  

           sitename1 = (String)hashtable1.get(s);  

         }  

        if(sitename1 == null)  

        //如果站點名為空值則站點名為默認(rèn)值http://www.yesky.com  

        sitename1 = "http://www.yesky.com";  

        String s2;  

        if(hashtable.get("log") != null && (s2 = getFileByUrl(hashtable, s1)) != null){  

         writeLog(hashtable, s2, sitename1, "c", httpservletrequest);  

         httpservletresponse.sendRedirect(sitename1);  

         }  

    private void showBanner(Hashtable hashtable, String s, HttpSession httpsession, HttpServletRequest httpservletrequest, HttpServletResponse httpservletresponse)  

    throws IOException  

    {  

     String s1 = (String)hashtable.get("dir");  

     File file = new File(s1);  

     Vector vector;  

     if(file == null)  

      {  

       vector = new Vector();  

      }  

     else  

      {  

       String as[] = file.list();  

       vector = getGraphFiles(as);  

      }  

     if(vector.size() == 0)  

      {  

       httpservletresponse.setContentType("text/html");  

       PrintWriter out = httpservletresponse.getWriter();  

       out.println("目錄是空的!");  

       out.flush();  
 
       out.close();  

       return;  

      }  

     int i;  

     if(httpsession != null)  

      synchronized(hashtable.get("dir"))  

      {  

       Integer integer;  

       int j;  

       if((integer = (Integer)httpsession.getValue("bi")) == null){  

        j = 0;  

       else  

        j = integer.intValue();  

        if(j >= vector.size()) {

         j = 0;  

         i = j;  

         if(++j >= 3){  

          j = 0;  

          httpsession.putValue("bi", new Integer(j));  

         }  

         else  

           i = 0;  

           String s2 = (String)vector.elementAt(i);  

           String s3;  

           if(httpsession != null && (s3 = getUrl(hashtable, s2)) != null)  

            {  

             Hashtable hashtable1;  

             if((hashtable1 = (Hashtable)httpsession.getValue("旗幟廣告系統(tǒng) ,Wayne Zheng")) == null){  

              hashtable1 = new Hashtable();  

              hashtable1.put(s, s3);  

              httpsession.putValue("旗幟廣告系統(tǒng) ,Wayne Zheng", hashtable1);  

              }  

             if(hashtable.get("log") != null) {

              writeLog(hashtable, s2, "v", httpservletrequest);  

              outputBanner(s2, hashtable, httpservletresponse);  

              vector = null;  

              }  



    private void writeLog(Hashtable logHashtable, String logString, String logString1, String logString2, HttpServletRequest httpservletrequest)//寫日志的函數(shù)  

    {  

     String logString3 = (String)hashtable.get("log");  

     String logString4 = getLogString(logString, httpservletrequest) + " \"" + logString1 + "\"";  

     GregorianCalendar gregoriancalendar = new GregorianCalendar();  

     //獲取當(dāng)前的時間  

     gregoriancalendar.setTime(new Date());  

     String logString5 = logString3 + stringDate(gregoriancalendar) + logString2 + ".txt";//以時間戳和“c”或“v”為文件名來寫日志文件  

     saveLog(hashtable, logString5, logString4);  

     }  



     private void writeLog(Hashtable logHashtable, String logString, String logString1, HttpServletRequest httpservletrequest) file://寫日志文件  

     {  

      String logString2 = (String)logHashtable.get("log");  

      String logString3 = getLogString(logString, httpservletrequest);  

      GregorianCalendar gregoriancalendar = new GregorianCalendar();  

      gregoriancalendar.setTime(new Date());  

      String logString4 = logString2 + stringDate(gregoriancalendar) + logString1 + ".txt";  

      saveLog(logHashtable, logString4, logString3);  

     }  

    private void saveLog(Hashtable hashtable, String s, String s1)//把日志文件保存在硬盤上  

     {  

       synchronized(hashtable.get("log"))  

      {  

       try  

        {  

         FileWriter filewriter = new FileWriter(s, true);  

         PrintWriter printwriter = new PrintWriter(filewriter);  

         printwriter.println(s1);  

         printwriter.flush();  

         printwriter.close();  

         filewriter.close();  

        }  

       catch(Exception _ex) { }  

     }  

    }  

   private String getLogString(String s, HttpServletRequest httpservletrequest)

    //取得日志字符串  

    {  

     String s1 = httpservletrequest.getRemoteAddr();  

     //取得遠(yuǎn)程的訪問者的IP地址  

     String s2 = httpservletrequest.getHeader("User-Agent");  

     String s3 = httpservletrequest.getHeader("Referer");  

     String s4 = "\"" + s + "\"";  

     if(s1 == null)  

      s1 = "-";  

      if(s2 == null)  

       s2 = "-";  

      else  

       s2 = "\"" + s2 + "\"";  

      if(s3 == null)  

       s3 = "-";  

      else  

       s3 = "\"" + s3 + "\"";  

      return s1 + " [" + new Date() + "] " + s4 + " " + s3 + " " + s2;  

     }  


   private String stringDate(Calendar calendar) //取得時間戳  

    {  

      String s = String.valueOf(calendar.get(1));  

      String s1 = String.valueOf(calendar.get(2));  

      if(s1.length() == 1)  

        s1 = "0" + s1;  

        s = s + s1;  

        s1 = String.valueOf(calendar.get(5));  

        if(s1.length() == 1)  

         s1 = "0" + s1;  

         return s + s1;  

       }  



    private String getFileByUrl(Hashtable hashtable, String s)  

     {  

      for(Enumeration enumeration = hashtable.keys(); enumeration.hasMoreElements();)  

       //hashtable的keys()方法返回了哈希表關(guān)鍵字的枚舉,enumeration的hasMoreElements()方法測試枚舉重是否還有其他元素  

       {  

        String s1 = (String)enumeration.nextElement();

         //讓s1的值為enumeration的下一個元素值  

        if(s.equals(hashtable.get(s1)))//如果s的值為s1的值,則  

         return s1;//返回s1的值  

       }  

       return null;  

      }  

    private String getFirstSite(Hashtable hashtable)//取得第一個站點的名字  

     {  

      String s = (String)hashtable.get("dir");  

      File file = new File(s);  

      if(file == null)  

        return null;  

        String as[] = file.list();  

        Vector vector = getGraphFiles(as);  

        //設(shè)置Vector向量變量來獲取圖形文件  

        if(vector.size() == 0)//如果沒有圖形文件,則返回空值  

          return null;  

        else  

          return getUrl(hashtable, (String)vector.elementAt(0));  

        }  

    private String getUrl(Hashtable hashtable, String s)//取得URL  

     {  

       String s1 = s.toLowerCase();//設(shè)置s1為s的小寫形式  

       for(Enumeration enumeration = hashtable.keys(); enumeration.hasMoreElements();)  

       {  

        String s2 = (String)enumeration.nextElement();  

        if(s1.equals(s2.toLowerCase()))  

         return (String)hashtable.get(s2);  

       }  

      return null;  

    }  

   private void outputBanner(String s, Hashtable hashtable, HttpServletResponse httpservletresponse)//輸出banner廣告  

    throws IOException//如果有錯則拋出IOException錯誤  

    {  

     String s1 = (String)hashtable.get("dir") + s;  

     httpservletresponse.setHeader("Cache-control", "no-store");  

     httpservletresponse.setHeader("Pragma", "no-cache");  

     httpservletresponse.setDateHeader("Expires", 1L);  

     httpservletresponse.setContentType("image/" + s.substring(s.indexOf(".") + 1));  

     javax.servlet.ServletOutputStream servletoutputstream = httpservletresponse.getOutputStream();  

     dumpFile(s1, servletoutputstream);  

     servletoutputstream.flush();  

     servletoutputstream.close();  

     }  

    private boolean dumpFile(String s, OutputStream outputstream)  

     {  

      byte abyte0[] = new byte[4096];  

      boolean flag = true;  

      try  

       {  

        FileInputStream fileinputstream = new FileInputStream(s);  

        int i;  

        while((i = fileinputstream.read(abyte0)) != -1)  

         outputstream.write(abyte0, 0, i);  

         fileinputstream.close();  

         }  

      catch(Exception _ex)  

      {  

       flag = false;  

       }  

       return flag;  

     }  

    private Vector getGraphFiles(String as[])//獲得圖片文件  

     {  

       Vector vector = new Vector();  

       if(as == null)//如果as為空值,則返回vector中的值  

        return vector;  

        for(int i = 0; i < as.length; i++)//as.length為as[]數(shù)組長度

        {

         String s = as[i].toUpperCase();//設(shè)置圖片文件文件名的每個字符為大寫

         if(isGraphFile(s))//如果為圖片格式

          vector.addElement(as[i]);//加入向量中

         }

         return vector;

       }

   private boolean isGraphFile(String stringFileName)

     //判斷文件是否為圖形格式

     {

      int i = stringFileName.indexOf(".");//

      if(i <= 0 i == stringFileName.length() - 1)

       return false;

       //判斷文件是否以GIF、JPG、JPEG或 PNG結(jié)尾

      String stringExtendFileName1 = stringFileName.substring(i + 1);

      return stringExtendFileName1.equals("GIF") stringExtendFileName1.equals("JPG") stringExtendFileName1.equals("JPEG") stringExtendFileName1.equals("PNG");

     }

    private void errorMessage(String s, HttpServletResponse httpservletresponse)

     throws IOException

     {

      httpservletresponse.setContentType("text/html");

      PrintWriter out = httpservletresponse.getWriter();

      out.println("");

      out.println("");

      out.println("");

      out.println("");

      out.println("");

      out.println("




" + s + "
");

      out.println("");

      out.println("");

      out.flush();

      out.close();

     }


   private String getFromQuery(String strQuery, String strQuery1)

    {

     if(strQuery == null)

      return "";

      int i;

      if((i = strQuery.indexOf(strQuery1)) < 0)

       return "";

       String strQuery2 = strQuery.substring(i + strQuery1.length());

      if((i = strQuery2.indexOf("&")) < 0)

        return strQuery2;

      else

        return strQuery2.substring(0, i);

      }


    public String getServletInfo()

     {

      return "旗幟廣告系統(tǒng) ,Wayne Zheng";

     }

   private static final String CPR = "? Wayne Zheng ";

   private static final String DEFAULT_SITE = "www.yesky.com";

   private static final String BANNER_SESSION = "旗幟廣告系統(tǒng) ,Wayne Zheng";

   private static final String DIR = "dir";

   private static final String LOG = "log";

   private static final String BANNERINDEX = "bi";

   private static final String EDITED = "edited";

   private static final String VIEW_POSTFIX = "v";

   private static final String CLICK_POSTFIX = "c";

   private static final String CONFIG = "config";

   private static final String MODE = "mode";
 
   private static final String ID = "id";

   private static final int BUFFER_SIZE = 4096;

   static String separator = "/";

   private static Hashtable cfgs;

   private static Hashtable logs;

  }