Java,J2EE,Weblogic,Oracle

          java項(xiàng)目隨筆
          隨筆 - 90, 文章 - 6, 評(píng)論 - 61, 引用 - 0

          導(dǎo)航

          常用鏈接

          留言簿(4)

          最新隨筆

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          jsp生成隨機(jī)驗(yàn)證碼


          服務(wù)器程序接收到表單數(shù)據(jù)后,首先判斷用戶(hù)是否填寫(xiě)了正確的驗(yàn)證碼,只有該驗(yàn)證碼與服務(wù)器端保存的驗(yàn)證碼匹配時(shí),服務(wù)器程序才開(kāi)始正常的表單處理流程。驗(yàn)證碼使用一次即失效,
          用戶(hù)只能重新向服務(wù)器發(fā)出訪問(wèn)表單填寫(xiě)頁(yè)面的請(qǐng)求來(lái)獲得新的驗(yàn)證碼,并填寫(xiě)新的驗(yàn)證碼后才能再次提交有效的表單請(qǐng)求, 這樣將大大 增加了用戶(hù)重復(fù)操作的難度。密碼猜測(cè)工具要逐一嘗試每個(gè)密碼的前題條件是先輸入正確的驗(yàn)證碼,而驗(yàn)證碼是一次性有效的,這樣基本上就阻斷了密碼猜測(cè)工具的自動(dòng)地處理過(guò)程
          下面編寫(xiě)一個(gè)利用
          Session 實(shí)現(xiàn)一次性驗(yàn)證碼的例子程序,整個(gè)程序包含 三個(gè)組件: check_code.html CheckCodeServlet.java LogonFormServlet.java check_code.html 是引用驗(yàn)證碼圖片的 FORM 表單頁(yè)面, CheckCodeServlet.java 是用于產(chǎn)生帶有隨機(jī)驗(yàn)證碼圖片的 Servlet 程序, LogonFormServlet.java 則是負(fù)責(zé)處理 FORM 表單請(qǐng)求的 Servlet 程序。

          : 動(dòng)手體驗(yàn): 利用 Session 實(shí)現(xiàn)一次性驗(yàn)證碼

          1 按上面描述的功能編寫(xiě)如 例程7-11、例程7-12和例程7-13所示的 程序。

          例程7-11 ? check_code.html

          ?


          <h3> 帶有驗(yàn)證碼的登錄頁(yè)面</h3>

          <form action="servlet/LogonFormServlet" method="post">

          用戶(hù)名:<input type="text" name="name"><br>

          密 碼:<input type="password" name="pass"><br>

          驗(yàn)證碼:<input type="text" name="check_code">

          <img src="servlet/CheckCodeServlet"><br>

          <input type="submit" value=" 登錄">

          </form>

          ?


          例程7-12 ? CheckCodeServlet .java

          ?


          import java.io.*;

          import javax.servlet.*;

          import javax.servlet.http.*;

          import java.awt.*;

          import java.awt.image.*;

          import javax.imageio.ImageIO;

          ?

          public class CheckCodeServlet extends HttpServlet

          {

          ?????? private static int WIDTH = 60;

          ?????? private static int HEIGHT = 20;

          ?????? public void doGet(HttpServletRequest request,HttpServletResponse response)

          ???????????????????? throws ServletException,IOException

          ?????? {???????????

          ????????????? HttpSession session = request.getSession();

          ????????????? response.setContentType("image/jpeg");

          ????????????? ServletOutputStream sos = response.getOutputStream();

          ?

          ????????????? // 設(shè)置瀏覽器不要緩存此圖片

          ????????????? response.setHeader("Pragma","No-cache");

          ????????????? response.setHeader("Cache-Control","no-cache");

          ????????????? response.setDateHeader("Expires", 0);

          ?????????????

          ????????????? // 創(chuàng)建內(nèi)存圖象并獲得其圖形上下文

          ????????????? BufferedImage image =

          ???????????????????? new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);

          ????????????? Graphics g = image.getGraphics();

          ?????????????

          ????????????? // 產(chǎn)生隨機(jī)的認(rèn)證碼

          ????????????? char [] rands = generateCheckCode();

          ?????????????

          ????????????? // 產(chǎn)生圖像

          ????????????? drawBackground(g);

          ????????????? drawRands(g,rands);

          ?????????????

          ????????????? // 結(jié)束圖像 的繪制 過(guò)程, 完成圖像

          ????????????? g.dispose();

          ?????????????

          ?????????????
          ????????????????? //
          將圖像輸出到客戶(hù)端

          ????????????? ByteArrayOutputStream bos = new ByteArrayOutputStream();

          ????????????? ImageIO.write(image, "JPEG", bos);

          ????????????? byte [] buf = bos.toByteArray();

          ????????????? response.setContentLength(buf.length);

          ????????????? // 下面的語(yǔ)句也可寫(xiě)成: bos.writeTo(sos);

          ????????????? sos.write(buf);

          ????????????? bos.close();

          ????????????? sos.close();

          ?

          ????????????? // 將當(dāng)前驗(yàn)證碼存入到 Session

          ????????????? session.setAttribute("check_code",new String(rands));

          ????????????? // 直接使用下面的代碼將有問(wèn)題, Session 對(duì)象必須在提交響應(yīng)前獲得

          ????????????? //request.getSession().setAttribute("check_code",new String(rands));

          ?????? }

          ??????

          ?????? private char [] generateCheckCode()

          ?????? {

          ????????????? // 定義驗(yàn)證碼的字符表

          ????????????? String chars = "0123456789abcdefghijklmnopqrstuvwxyz";

          ????????????? char [] rands = new char[4];

          ????????????? for(int i=0; i<4; i++)

          ????????????? {

          ???????????????????? int rand = (int)(Math.random() * 36);

          ???????????????????? rands[i] = chars.charAt(rand);

          ????????????? }

          ????????????? return rands;

          ?????? }

          ??????

          ?????? private void drawRands(Graphics g , char [] rands)

          ?????? {

          ????????????? g.setColor(Color.BLACK);

          ????????????? g.setFont(new Font(null,Font.ITALIC|Font.BOLD,18));

          ????????????? // 在不同的高度上輸出驗(yàn)證碼的每個(gè)字符 ????????

          ????????????? g.drawString("" + rands[0],1,17);

          ????????????? g.drawString("" + rands[1],16,15);

          ????????????? g.drawString("" + rands[2],31,18);

          ????????????? g.drawString("" + rands[3],46,16);

          ????????????? System.out.println(rands);

          ?????? }

          ??????

          ?????? private void drawBackground(Graphics g)

          ?????? {

          ???????????? // 畫(huà)背景

          ????????????? g.setColor(new Color(0xDCDCDC));

          ????????????? g.fillRect(0, 0, WIDTH, HEIGHT);

          ????????????? // 隨機(jī)產(chǎn)生 120 個(gè)干擾點(diǎn)

          ????????????? for(int i=0; i<120; i++)

          ????????????? {

          ???????????????????? int x = (int)(Math.random() * WIDTH);

          ???????????????????? int y = (int)(Math.random() * HEIGHT);

          ???????????????????? int red = (int)(Math.random() * 255);

          ???????????????????? int green = (int)(Math.random() * 255);

          ???????????????????? int blue = (int)(Math.random() * 255);

          ???????????????????? g.setColor(new Color(red,green,blue));???????

          ???????????????????? g.drawOval(x,y,1,0);

          ????????????? }

          ?????? }

          }

          ?


          例程 7-13 ? LogonFormServlet .java

          ?


          import java.io.*;

          import javax.servlet.*;

          import javax.servlet.http.*;

          ?

          public class LogonFormServlet extends HttpServlet

          {

          ?????? public void service(HttpServletRequest request,

          ????????????? HttpServletResponse response) throws ServletException, IOException

          ?????? {

          ????????????? response.setContentType("text/html;charset=GB2312");?????????????????????????

          ????????????? PrintWriter out = response.getWriter();

          ?????????????

          ????????????? HttpSession session = request.getSession(false);

          ????????????? if(session == null)

          ????????????? {

          ???????????????????? out.println(" 驗(yàn)證碼處理問(wèn)題 !");

          ???????????????????? return;

          ????????????? }

          ?????????????

          ????????????? String savedCode = (String)session.getAttribute("check_code");

          ????????????? if(savedCode == null)

          ????????????? {

          ???????????????????? out.println(" 驗(yàn)證碼處理問(wèn)題 !");

          ???????????????????? return;

          ????????????? }

          ???????????????????????????

          ????????????? String checkCode = request.getParameter("check_code");

          ????????????? if(!savedCode.equals(checkCode))

          ????????????? {

          ???????????????????? /* 驗(yàn)證碼未通過(guò),不從 Session 中清除原來(lái)的驗(yàn)證碼,

          ???????????????????? 以便用戶(hù)可以后退回登錄頁(yè)面繼續(xù)使用原來(lái)的驗(yàn)證碼進(jìn)行登錄 */

          ???????????????????? out.println(" 驗(yàn)證碼無(wú)效 !");

          ???????????????????? return;

          ????????????? }

          ????????????? /* 驗(yàn)證碼檢查通過(guò)后,從 Session 中清除原來(lái)的驗(yàn)證碼,

          ????????????? 以防用戶(hù)后退回登錄頁(yè)面繼續(xù)使用原來(lái)的驗(yàn)證碼進(jìn)行登錄 */

          ????????????? session.removeAttribute("check_code");

          ????????????? out.println(" 驗(yàn)證碼通過(guò),服務(wù)器正在校驗(yàn)用戶(hù)名和密碼 !");

          ?????? }

          }

          ?


          編譯上面的兩個(gè) Java 文件,確保編譯后生成的class文件存放在了 < tomcat 安裝目錄 >\webapps\it315\WEB-INF\classes 目錄中。將 check_code.html 文件保存在 < tomcat 安裝目錄 > \webapps\it315 目錄中。

          2 )在 < tomcat 安裝目錄 > \webapps\it315\WEB-INF\web.xml 文件中注冊(cè)有關(guān)的Servlet,并設(shè)置其映射URL。在web.xml文件中的相應(yīng)位置處增加如下兩段內(nèi)容:

          ?????? <servlet>

          ????????????? <servlet-name>CheckCodeServlet</servlet-name>

          ????????????? <servlet-class>CheckCodeServlet</servlet-class>

          ?????? </servlet>???

          ?????? <servlet>

          ????????????? <servlet-name>LogonFormServlet</servlet-name>

          ????????????? <servlet-class>LogonFormServlet</servlet-class>

          ?????? </servlet>?

          ?????? ……

          ?????? <servlet-mapping>

          ????????????? <servlet-name>CheckCodeServlet</servlet-name>

          ????????????? <url-pattern>/servlet/CheckCodeServlet</url-pattern>

          ?????? </servlet-mapping>

          ?????? <servlet-mapping>

          ????????????? <servlet-name>LogonFormServlet</servlet-name>

          ????????????? <url-pattern>/servlet/LogonFormServlet</url-pattern>

          ?????? </servlet-mapping>?????????????????

          保存 web.xml 文件后,重新啟動(dòng) Tomcat

          3 )在瀏覽器地址欄中輸入如下地址:

          ?????? http://localhost:8080/it315/check_code.html

          瀏覽器中顯示出如圖 7.25 所示的效果 ,然后就可以對(duì)驗(yàn)證碼的功能進(jìn)行測(cè)試了。

          posted on 2006-11-20 16:15 龔椿深 閱讀(5005) 評(píng)論(7)  編輯  收藏

          評(píng)論

          # re: jsp生成隨機(jī)驗(yàn)證碼  回復(fù)  更多評(píng)論   

          ;sad;flsadkfdsf
          2007-12-17 21:00 | xiao

          # re: jsp生成隨機(jī)驗(yàn)證碼  回復(fù)  更多評(píng)論   

          外兒童歌溫柔我⑤他5熱 人
          2009-05-21 21:57 | 澀容易會(huì)突然

          # re: jsp生成隨機(jī)驗(yàn)證碼[未登錄](méi)  回復(fù)  更多評(píng)論   

          驗(yàn)證碼顯示不出來(lái)咯
          2010-06-21 17:18 | yy

          # re: jsp生成隨機(jī)驗(yàn)證碼[未登錄](méi)  回復(fù)  更多評(píng)論   

          bdsb
          2013-10-24 18:06 |

          # re: jsp生成隨機(jī)驗(yàn)證碼  回復(fù)  更多評(píng)論   

          打發(fā)水電費(fèi)
          2014-01-06 16:42 | 發(fā)撒旦

          # re: jsp生成隨機(jī)驗(yàn)證碼  回復(fù)  更多評(píng)論   

          呆呆呆呆呆呆
          2014-01-06 16:42 | 發(fā)撒旦

          # 123  回復(fù)  更多評(píng)論   

          12
          2015-08-16 22:41 | 11

          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 宣恩县| 九江县| 博客| 黄梅县| 营山县| 左权县| 古丈县| 仁化县| 涟源市| 临洮县| 湖北省| 汪清县| 长岭县| 宁德市| 北宁市| 英德市| 邹城市| 汕尾市| 枣庄市| 永济市| 时尚| 盐津县| 松阳县| 灯塔市| 温宿县| 桂平市| 建昌县| 西贡区| 达州市| 洪湖市| 黎平县| 南京市| 博湖县| 临猗县| 浦江县| 永州市| 墨竹工卡县| 泰来县| 柳江县| 晴隆县| 南投市|