国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

J2EE驗(yàn)證碼圖片如何生成和點(diǎn)擊刷新驗(yàn)證碼

2019-11-26 14:23:46
字體:
供稿:網(wǎng)友

驗(yàn)證碼圖片生成步驟

創(chuàng)建BufferedImage對(duì)象。
獲取BufferedImage的畫筆,即調(diào)用getGraphics()方法獲取Graphics對(duì)象。
調(diào)用Graphics對(duì)象的setColor()方法和fillRect()方法設(shè)置圖片背景顏色。
調(diào)用Graphics對(duì)象的setColor()方法和drawLine()方法設(shè)置圖片干擾線。
調(diào)用BufferedImaged對(duì)象的setRGB()方法設(shè)置圖片的噪點(diǎn)。
調(diào)用Graphics對(duì)象的setColor()方法、setFont()方法和drawString()方法設(shè)置圖片驗(yàn)證碼。

因?yàn)轵?yàn)證碼的圖片的寬度和高度要根據(jù)網(wǎng)站的風(fēng)格來確定的,所以字體的大小需要根據(jù)圖片的寬度和高度來確定,用到了小小的技巧。

package util;import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.Image;import java.awt.image.BufferedImage;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.util.Random;import javax.imageio.ImageIO;public class Verification {  private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";    /**   * 生成一個(gè)寬為width, 高為height, 驗(yàn)證碼為code的圖片   * @param width 圖片的寬   * @param height 圖片的高   * @param code 驗(yàn)證碼字符串   * @return 返回圖片驗(yàn)證碼   */  public static BufferedImage getImage(int width, int height, String code){    return getImage(width, height, code, 20);  }  /**   * 生成一個(gè)寬為width, 高為height, 驗(yàn)證碼為code的圖片,圖片中干擾線的條數(shù)為lineCnt   * @param width 圖片的寬   * @param height 圖片的高   * @param code 驗(yàn)證碼字符串   * @param lineCnt 干擾線的條數(shù),建議為10條左右,可根據(jù)結(jié)果適當(dāng)調(diào)整   * @return 返回圖片驗(yàn)證碼   */  public static BufferedImage getImage(int width, int height, String code, int lineCnt){    return createImage(width, height, code, lineCnt, 0.01);  }  /**   * 生成一個(gè)寬為width, 高為height, 驗(yàn)證碼為code的圖片,圖片中干擾線的條數(shù)為lineCnt   * 噪聲比為noiseRate,即圖片中噪音像素點(diǎn)的百分比   * @param width 圖片的寬   * @param height 圖片的高   * @param code 驗(yàn)證碼字符串   * @param lineCnt 干擾線的條數(shù),建議為10條左右,可根據(jù)結(jié)果適當(dāng)調(diào)整   * @param noiseRate 圖片中噪音像素點(diǎn)占總像素的百分比   * @return 返回圖片驗(yàn)證碼   */  public static BufferedImage getImage(int width, int height, String code, int lineCnt, double noiseRate){    return createImage(width, height, code, lineCnt, noiseRate);  }    /**   *    * 生成一個(gè)寬為width, 高為height, 驗(yàn)證碼為code的圖片,圖片中干擾線的條數(shù)為lineCnt   * 噪聲比為noiseRate,即圖片中噪音像素點(diǎn)的百分比   * @param width 圖片的寬   * @param height 圖片的高   * @param code 驗(yàn)證碼字符串   * @param lineCnt 干擾線的條數(shù),建議為10條左右,可根據(jù)結(jié)果適當(dāng)調(diào)整   * @param noiseRate 圖片中噪音像素點(diǎn)占總像素的百分比   * @return 返回圖片驗(yàn)證碼   */  private static BufferedImage createImage(int width, int height, String code, int lineCnt, double noiseRate){    int fontWidth = ((int)(width * 0.8)) / code.length();    int fontHeight = (int)(height * 0.7);    //為了在任意的width和height下都能生成良好的驗(yàn)證碼,    //字體的大小為fontWdith何fontHeight中的小者,    int fontSize = Math.min(fontWidth, fontHeight);    //drawString時(shí)要用到    int paddingX = (int) (width * 0.1);    int paddingY = height - (height - fontSize) / 2;        //創(chuàng)建圖像    BufferedImage buffimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);    //獲得畫筆    Graphics g = buffimg.getGraphics();    //設(shè)置畫筆的顏色    g.setColor(getRandColor(200, 255));    //然后填充一個(gè)矩形,即設(shè)置背景色    g.fillRect(0, 0, width, height);        // 設(shè)置干擾線    for (int i = 0; i < lineCnt; i++) {        //隨機(jī)獲取干擾線的起點(diǎn)和終點(diǎn)      int xs = (int)(Math.random() * width);      int ys = (int)(Math.random() * height);      int xe = (int)(Math.random() * width);      int ye = (int)(Math.random() * height);      g.setColor(getRandColor(1, 255));      g.drawLine(xs, ys, xe, ye);    }    // 添加噪點(diǎn)    int area = (int) (noiseRate * width * height);    for(int i=0; i<area; ++i){        int x = (int)(Math.random() * width);        int y = (int)(Math.random() * height);        buffimg.setRGB(x, y, (int)(Math.random() * 255));    }    //設(shè)置字體    Font font = new Font("Ravie", Font.PLAIN, fontSize);    g.setFont(font);        for(int i=0; i<code.length(); ++i){        String ch = code.substring(i, i+1);        g.setColor(getRandColor(1, 199));        g.drawString(ch, paddingX + fontWidth * i, paddingY);    }    return buffimg;      }  /**   * 獲取隨機(jī)的顏色,r,g,b的取值在L到R之間   * @param L 左區(qū)間   * @param R 右區(qū)間   * @return 返回隨機(jī)顏色值   */  private static Color getRandColor(int L, int R){    if(L > 255)      L = 255;    if(R > 255)      R = 255;    if(L < 0)      L = 0;    if(R < 0)      R = 0;    int interval = R - L;     int r = L + (int)(Math.random() * interval);    int g = L + (int)(Math.random() * interval);    int b = L + (int)(Math.random() * interval);    return new Color(r, g, b);  }  /**   * 隨機(jī)生成若干個(gè)由大小寫字母和數(shù)字組成的字符串   * @param len 隨機(jī)生成len個(gè)字符   * @return 返回隨機(jī)生成的若干個(gè)由大小寫字母和數(shù)字組成的字符串   */  public static String getRandCode(int len){    String code = "";    for(int i=0; i<len; ++i){      int index = (int)(Math.random() * ALPHABET.length());      code = code + ALPHABET.charAt(index);    }    return code;  }  /**   * 將圖片轉(zhuǎn)為byte數(shù)組   * @param image 圖片   * @return 返回byte數(shù)組   * @throws IOException   */  public static byte[] getByteArray(BufferedImage image) throws IOException{    ByteArrayOutputStream baos = new ByteArrayOutputStream();    ImageIO.write(image, "png", baos);    return baos.toByteArray();    //ByteArrayOutputStream 不需要close      }}

使用驗(yàn)證碼圖片

在verificationCode.java這個(gè)servlet中調(diào)用上面的類生成驗(yàn)證碼圖片,然后將圖片返回給客戶端。

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {    HttpSession session = request.getSession();    //隨機(jī)生成字符串,并寫入session    String code = Verification.getRandCode(4);    session.setAttribute("verification", code);    BufferedImage image = util.Verification.getImage(100,30, code, 5);    response.setContentType("image/png");        OutputStream out = response.getOutputStream();    out.write(util.Verification.getByteArray(image));    out.flush();    out.close();      } 

在index.jsp中設(shè)置驗(yàn)證碼,用戶點(diǎn)擊驗(yàn)證碼時(shí),調(diào)用js代碼請(qǐng)求服務(wù)器得到新的驗(yàn)證碼。因?yàn)樯厦娴哪莻€(gè)生成驗(yàn)證碼的servlet會(huì)被瀏覽器緩存,所以js代碼中需要給該servlet一個(gè)隨機(jī)的參數(shù),這樣瀏覽器就會(huì)向服務(wù)器發(fā)請(qǐng)求得到新的驗(yàn)證碼,而不是去緩存中讀取。

<%@page import="util.Verification"%><%@ 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>Insert title here</title><script type="text/javascript">    function refreshcode(){      document.getElementById("verification").src= "/verificationCode/verificationCode?hehe="+Math.random();    }  </script></head><body>    <form action="<%=request.getContextPath()+"/checkVerification" %>" method="post">    驗(yàn)證碼:<input type="text" name="submitVerification">    <img id="verification" alt="" title="看不清點(diǎn)擊刷新驗(yàn)證碼" src="<%=request.getContextPath()+"/verificationCode" %>"    onclick="refreshcode()"><br>    <input type="submit" name="submit" value="提交">  </form>  </body></html>

最后是在checkVerification.java這個(gè)servlet中判斷用戶輸入的驗(yàn)證碼是否正確,為了方便用戶,驗(yàn)證碼一般都設(shè)置成大小寫不敏感,所以要先轉(zhuǎn)化為小寫字母再比對(duì)。

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  HttpSession session = request.getSession();  String verification = (String)session.getAttribute("verification");  String submitVerification = request.getParameter("submitVerification");  PrintWriter out = response.getWriter();  if(verification!=null && submitVerification!=null){   if(verification.toLowerCase().equals(submitVerification.toLowerCase())){    out.println("yes!!!");   }   else{    out.println("no!!!");   }     }  else{   out.println("no!!!");  }  session.removeAttribute("verification");//防止用戶重復(fù)提交表單 } /**  * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)  */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  // TODO Auto-generated method stub  doGet(request, response); }

最后運(yùn)行的效果圖如下

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 隆安县| 芜湖县| 石景山区| 丰城市| 浠水县| 乌拉特中旗| 固始县| 昆山市| 汝阳县| 长阳| 开化县| 株洲市| 怀集县| 阳春市| 石屏县| 神木县| 公安县| 孝义市| 绥阳县| 兴国县| 广安市| 乌兰察布市| 怀来县| 綦江县| 工布江达县| 蓬莱市| 凤翔县| 双峰县| 盐源县| 海丰县| 明水县| 苏州市| 左贡县| 石首市| 大渡口区| 台州市| 台州市| 全州县| 原阳县| 紫金县| 绥化市|