dyerac  
          dyerac In Java
          公告

          日歷
          <2006年8月>
          303112345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789
          統計
          • 隨筆 - 36
          • 文章 - 10
          • 評論 - 94
          • 引用 - 0

          導航

          常用鏈接

          留言簿(5)

          隨筆分類(49)

          隨筆檔案(36)

          文章分類(11)

          文章檔案(10)

          相冊

          dyerac

          搜索

          •  

          積分與排名

          • 積分 - 79790
          • 排名 - 705

          最新隨筆

          最新評論

          閱讀排行榜

          評論排行榜

           

          ???? 在web系統中,驗證碼的應用基本上隨處可見.驗證碼可以防止他人惡意攻擊和垃圾注冊,可以說已成了web開發中必不可少的環節.遺憾的是,驗證碼在jsp,jsf的組件庫, 至少是一些標準的組件庫中并沒有出現.本文分別介紹如何在jsp和jsf中使用驗證碼和我的一些小經驗,呵呵.
          ???? 在jsp中,我們使用apache的taglibs-image(http://jakarta.apache.org/taglibs/sandbox/doc/image-doc/intro.html),可以簡便的配置自己的驗證碼.而由于在jsf中,無法和其他jsp標簽庫混用(至少不能和上述標簽庫混用),我們則用Java2D自己繪制驗證碼圖.
          ?

          1. 在jsp中使用taglibs-image部署驗證碼
          ??? taglibs-image可以通過標簽自動將一段文字和背景圖片生成新的圖片,文字的布局,顏色,字體等等都可以自我定制,因此拿來做驗證碼是非常的簡單
          ???

          <% @?page?contentType = " text/html;?charset=iso-8859-1 " ?language = " java " ? import = " java.sql.* " ?errorPage = "" ? %>
          <% @?taglib?uri = " http://jakarta.apache.org/taglibs/image-1.0 " ?prefix = " img " ? %>

          < html >
          < head >
          < title > Image?Tag?examples </ title >
          < meta?http - equiv = " Content-Type " ?content = " text/html;?charset=iso-8859-1 " >
          </ head >

          < body >
          td
          ?
          <%
          ??
          int ?num? = ?( int )?java.lang.Math.round(java.lang.Math.random()? * ? 8999 );
          ??String?sRand?
          = ? "" ? + ?( 1000 ? + num);
          ??session.setAttribute(
          " userInfo.authcode " ,sRand);
          ?
          %>
          < img:image?src = " /images/code.gif " ?refresh = " true " >
          ??
          < img:text?text = " <%=sRand.substring(0,1)%> " ?x = " 18% " ?
          ????????y
          = " 25% " ?
          ????????font
          = " Arial " ?
          ????????bold
          = " true " ?
          ????????size
          = " 16 " ?
          ????????
          />
          ??
          < img:text?text = " <%=sRand.substring(1,2)%> " ?x = " 36% " ?
          ????????y
          = " 15% " ?
          ????????font
          = " Times?New?Roman " ?
          ????????bold
          = " true " ?
          ????????size
          = " 20 " ?
          ????????
          />
          ??
          < img:text?text = " <%=sRand.substring(2,3)%> " ?x = " 60% " ?
          ????????y
          = " 20% " ?
          ????????font
          = " Arial " ?
          ????????bold
          = " true " ?
          ????????size
          = " 18 " ?
          ????????
          />
          ??
          < img:text?text = " <%=sRand.substring(3,4)%> " ?x = " 77% " ?
          ????????y
          = " 30% " ?
          ????????font
          = " Times?New?Roman " ?
          ????????bold
          = " true " ?
          ????????size
          = " 14 " ?
          ????????
          />
          </ img:image >
          </ body >
          </ html >

          ?? 其中最開始百分號內的java代碼是為了生成驗證碼,然后保存在session中.同時驗證碼和背景圖片生成新的驗證圖.用戶根據此圖輸入驗證碼.在服務器方,只用把用戶提交表單中的驗證碼內容取出和session中保存的驗證碼對比,就可以判斷正確性咯
          ?????????????

          2.JSF
          ?? jsf中無法使用上述標簽(會無法渲染出來), 因此,我們自己實現一個生成驗證圖的類,再通過jsf的<h:graphicImage>標簽得以顯示.
          ? 生成驗證碼的java類如下:
          package?org.myibm.beans;

          import?java.awt.Color;
          import?java.awt.Font;
          import?java.awt.Graphics;
          import?java.awt.image.BufferedImage;
          import?java.io.File;
          import?java.io.IOException;
          import?java.util.Random;

          import?javax.imageio.ImageIO;

          /**
          ?*?用來自動生成驗證圖和驗證碼,驗證圖是背景圖加上干擾點加上驗證碼
          ?*?
          ?*?
          @author?td
          ?*?
          ?
          */

          public?final?class?CodeImageGenerator?{
          ????
          private?final?static?int?DEF_WIDTH?=?60;

          ????
          private?final?static?int?DEF_HEIGHT?=?20;

          ????
          private?final?static?String?BASE_PATH?=?"validate-images";

          ????
          /**
          ?????*?驗證碼
          ?????
          */

          ????
          private?String?code?=?"";

          ????
          /**
          ?????*?驗證圖的地址
          ?????
          */

          ????
          private?String?path;

          ????
          private?int?width;

          ????
          private?int?height;

          ????
          private?BufferedImage?image;

          ????
          /**
          ?????*?驗證圖對應的File對象
          ?????
          */

          ????
          private?File?target;

          ????
          public?CodeImageGenerator()?{
          ????????
          this(DEF_WIDTH,?DEF_HEIGHT);
          ????}


          ????
          public?CodeImageGenerator(int?width,?int?height)?{
          ????????
          this.width?=?width;
          ????????
          this.height?=?height;
          ????????generateCodeImage();
          ????}


          ????
          /**
          ?????*?生成驗證碼和驗證圖
          ?????*
          ?????
          */

          ????
          private?void?generateCodeImage()?{
          ????????
          //?create?the?image
          ????????image?=?new?BufferedImage(width,?height,?BufferedImage.TYPE_INT_RGB);
          ????????Graphics?g?
          =?image.getGraphics();
          ????????
          //?set?the?background?color
          ????????g.setColor(new?Color(0xDCDCDC));
          ????????g.fillRect(
          0,?0,?width,?height);
          ????????
          //?draw?the?border
          ????????g.setColor(Color.black);
          ????????g.drawRect(
          0,?0,?width?-?1,?height?-?1);
          ????????
          //?set?the?font
          ????????g.setFont(new?Font("Times?New?Roman",?Font.PLAIN,?18));
          ????????
          //?create?a?random?instance?to?generate?the?codes
          ????????Random?random?=?new?Random();
          ????????
          //?make?some?confusion
          ????????for?(int?i?=?0;?i?<?50;?i++)?{
          ????????????
          int?x?=?random.nextInt(width);
          ????????????
          int?y?=?random.nextInt(height);
          ????????????g.drawOval(x,?y,?
          0,?0);
          ????????}
          ?//?generate?a?random?code
          ????????for?(int?i?=?0;?i?<?4;?i++)?{
          ????????????String?rand?
          =?String.valueOf(random.nextInt(10));
          ????????????code?
          +=?rand;
          ????????????g.drawString(rand,?
          13?*?i?+?6,?16);
          ????????}

          ????????g.dispose();
          ????????
          try?{
          ????????????File?dir?
          =?new?File("K:/Tomcat?5.5/webapps/nirvana/validate-images");
          ????????????String?s?
          =?new?Double(Math.random()?*?995596390219L).toString();
          ????????????File?imgFile?
          =?new?File(dir,?s?+?".jpeg");
          ????????????
          if?(!imgFile.exists())
          ????????????????imgFile.createNewFile();
          ????????????target?
          =?imgFile;
          ????????????ImageIO.write(image,?
          "JPEG",?imgFile);
          ????????????path?
          =?"/"?+?BASE_PATH?+?"/"?+?s?+?".jpeg";
          ????????????System.err.println(path);
          ????????}
          ?catch?(IOException?e)?{
          ????????????
          //?TODO?Auto-generated?catch?block
          ????????????e.printStackTrace();
          ????????}

          ????}


          ????
          public?BufferedImage?getImage()?{
          ????????
          return?image;
          ????}


          ????
          public?String?getCode()?{
          ????????
          if?(code?==?null)
          ????????????code?
          =?"";
          ????????
          return?code;
          ????}


          ????
          public?static?void?main(String[]?args)?throws?Exception?{
          ????????
          //?File?imgFile?=?new?File("codeImage.jpeg");
          ????????
          //?CodeImageGenerator?cig?=?new?CodeImageGenerator();
          ????????
          //?ImageIO.write(cig.getImage(),?"JPEG",?imgFile);
          ????}


          ????
          public?String?getPath()?{
          ????????
          return?path;
          ????}


          ????
          public?void?setPath(String?path)?{
          ????????
          this.path?=?path;
          ????}


          ????
          /**
          ?????*?當這個對象被回收時,同時銷毀其對應的驗證圖
          ?????
          */

          ????@Override
          ????
          protected?void?finalize()?throws?Throwable?{
          ????????
          //?TODO?Auto-generated?method?stub
          ????????
          //?System.err.println("finalize");
          ????????if?(target.exists())
          ????????????target.delete();
          ????????
          super.finalize();
          ????}


          ????
          public?File?getTarget()?{
          ????????
          return?target;
          ????}


          ????
          public?void?setTarget(File?target)?{
          ????????
          this.target?=?target;
          ????}

          }


          要說明幾點的事,這個類會把生成的驗證圖放在制定文件夾下,未免得文件越來越多,應該當驗證圖不再使用時將之刪除.所以此類重寫了Object的finalize()方法,當此類被垃圾回收器回收時,同時也刪除其對應的驗證圖.
          這樣,就可以利用java的垃圾回收器輕松為我們刪除不用的文件.

          另外,在頁面對應的managed-bean中,我們還要添加如何得到驗證碼和驗證圖的方法

          private?CodeImageGenerator?validator;
          ????
          ????
          private?String?validate_code;
          ????
          ????
          public?CodeImageGenerator?getValidator()?{
          ????????
          if(validator!=null){
          ????????????validator.getTarget().delete();
          ????????????validator
          =null;
          ????????}

          ????????validator
          =new?CodeImageGenerator();
          ????????System.out.println(validator.getCode());
          ????????
          return?validator;
          ????}


          ????
          public?void?setValidator(CodeImageGenerator?validator)?{
          ????????
          this.validator?=?validator;
          ????}

          其中validate-code對應用戶輸入的驗證碼信息
          因為每次刷新頁面都需要得到不同的驗證碼,所以在getValidator()方法時,每次需要返回一個新的CodeImageGenerator.同時,你可能等不及垃圾回收器幫你刪除文件,因此,可以在這里同時刪除老的驗證圖.

          另外,在注冊時我們還需要做一下判斷:
          public?String?register()?{
          ????????
          //?System.out.println("haha");
          ????????if(!validator.getCode().equals(validate_code)){
          ????????????FacesMessage?message?
          =?new?FacesMessage(
          ????????????????????FacesMessage.SEVERITY_ERROR,?
          "驗證碼錯誤",
          ????????????????????
          "驗證碼錯誤");
          ????????????FacesContext.getCurrentInstance().addMessage(
          null,?message);
          ????????????FacesContext?fcg?
          =?FacesContext.getCurrentInstance();
          ????????????((LoginBean)?fcg.getApplication().getVariableResolver()
          ????????????????????.resolveVariable(fcg,?
          "loginBean")).setReg(true);
          ????????????System.out.println(validator.getCode());
          ????????????System.out.println(validate_code);
          ????????????
          return?null;
          ????????}

          ..
          }

          最后,我們需要在頁面中添加對應的標簽


          ????????????????????????<h:outputText?value="驗證碼(*):"?styleClass="label"></h:outputText>
          ????????????????????????
          <h:message?for="vcode"?styleClass="error"></h:message>

          ????????????????????????
          <h:inputText?id="vcode"?required="true"?value="#{myPageBean.validate_code}"></h:inputText>
          ????????????????????????
          <h:graphicImage?value="#{myPageBean.validator.path}"></h:graphicImage>

          這樣, 我們就在jsf中實現了自己的驗證碼部署^_^

          posted on 2006-08-03 12:52 dyerac in java... 閱讀(2764) 評論(1)  編輯  收藏 所屬分類: 原創文章JavaEE
          評論:
          • # re: 在web應用中部署你自己的驗證碼(jsp,jsf兩種方式)[未登錄]  ken Posted @ 2009-07-04 07:48
            頁面用的那個標簽沒有辦法顯示 圖片,現實的是紅色叉叉

            請教如何解決?

            niceken520@gmail.com  回復  更多評論   

           
          Copyright © dyerac in java... Powered by: 博客園 模板提供:滬江博客
          主站蜘蛛池模板: 清原| 定日县| 五原县| 二连浩特市| 上犹县| 信阳市| 裕民县| 屏南县| 永城市| 平南县| 图木舒克市| 太康县| 花垣县| 陕西省| 岚皋县| 龙州县| 玛曲县| 清水县| 海口市| 沾化县| 溧阳市| 枣庄市| 固安县| 白河县| 邵武市| 河西区| 民乐县| 仁布县| 通州市| 江安县| 红桥区| 醴陵市| 楚雄市| 汪清县| 商城县| 保康县| 青川县| 隆昌县| 楚雄市| 江孜县| 高平市|