1. 程式人生 > >註冊登入(設計圖片驗證碼)

註冊登入(設計圖片驗證碼)

圖片驗證碼的實現 (註冊、下單、支付均有涉及)

1. 目的:

1) 驗證操作者是否是人,不是機器。
2) 防止表單重複提交。每次提交要判斷驗證碼的正確與否

生成驗證碼的要點:
1) 使用java程式碼生成圖片物件
2) 使用Random生成隨機字串
3) 將圖片物件用
ImageIO.write(圖片物件, “jpeg|png”, 響應位元組輸出流)
返回給客戶端瀏覽器
驗證驗證碼:
要點:
1) 將驗證碼文字存入session作用域
2) 表單提交時,對比session中的驗證碼和表單中的驗證碼,用來判斷驗證碼輸入是否正確

2.程式碼實現:

第一步:建立圖片

 public class CaptchaUtil {
  public static String[] array = {"a", "b", "c", "d", "e", "f", "g"};
   public static String random() {
    Random random = new Random();
    StringBuffer sb = new StringBuffer(3);
   //如果超出3,系統會自動擴充,一般情況下,將隨機數數字設定在範圍內,例如3,4,5,6 以new StringBuffer(3)為標準最佳
for (int i = 0; i < 3; i++) {
        int i1 = random.nextInt(array.length);
        sb.append(array[i1]);

   }
    return sb.toString();
}
public static void outputImage(String str, OutputStream os) {
    //建立圖片
    BufferedImage image = new BufferedImage(100, 80, BufferedImage.TYPE_INT_BGR);
    //物件獲得畫布
    Graphics g = image.getGraphics();
    //作畫,背景色
    g.setColor(Color.WHITE);
    g.fillRect(0, 0, 100, 80);
    //前景色
    g.setColor(Color.BLUE);
    //設定字型
    g.setFont(new Font("宋體", Font.PLAIN, 36));
    //寫字
    g.drawString(str, 0, 40);
    //輸出結果
    try {
        ImageIO.write(image, "png", os);
    } catch (IOException e) {
        e.printStackTrace();
    }
    }
public static void main(String[] args) throws IOException {
    String str = random();
    outputImage(str, new FileOutputStream("e:\\2.png"));
}
  }

第二步:將隨機產生的字串存入session中,並且讓圖片作為響應

 @WebServlet(urlPatterns = "/captcha.png")
public class CatcherServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req,       HttpServletResponse resp) throws ServletException,   IOException {
    resp.setContentType("image/png");
    String s = CaptchaUtil.random();
     //將隨機產生的字串存入session作用域,便於圖片驗證碼驗證時對比
    req.getSession().setAttribute("captcha",s);
      //圖片作為響應 resp.getoutputStream()
      CaptchaUtil.outputImage(s,resp.getOutputStream());
}
}

第三步:表單提交部分

<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/register" method="post">
<table>
    <tr>
        <td>使用者名稱</td>
        <td><input type="text" name="username" id="username"></td>
    </tr>
    <tr>
        <td>密碼</td>
        <td><input type="password" name="password" id="password"></td>
    </tr>
    <tr>
        <%--圖片的地址就是獲取圖片的servlet的地址--%>
        <td><img src="/captcha.png" onclick="changeImg(this)"></td>
        <td><input type="text" name="captcha">  ${requestScope.error} </td>
      </tr>
    <tr>
        <td colspan="2"><input type="submit" value="註冊"> </td>
    </tr>
</table>
</form>
<script>
// 點選事件是為了每次點選圖片驗證碼,驗證碼都會變化,由於考慮到個別瀏覽器的快取,圖片不會變化,所以我們+new Date().getTime()
  function changeImg(img)
{
    img.src="/captcha.png?t="+new Date().getTime();
}    
</script>
</body>
</html>

第四步: 提交後驗證輸入的驗證碼是否正確,如果不正確,重新調回提交介面(這裡旨在校驗驗證碼功能,沒有獲取判斷使用者名稱等提交資訊,驗證成功後只在控制檯輸出“驗證成功”字樣,僅僅為檢視效果,實際情況下,驗證成功過後應跳轉到其他介面)

@WebServlet(urlPatterns = "/register")
public class RegisterServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String captcha = req.getParameter("captcha");
    Object captcha1 = req.getSession().getAttribute("captcha");
    if(captcha !=null && captcha.equals(captcha1)){
        //判斷得出驗證碼和所填寫的驗證碼一致,表示填寫正確
        req.getSession().removeAttribute("captcha1");//銷燬session值
        System.out.println("驗證成功");
    }
    else {
        req.setAttribute("error","驗證碼不正確");
        req.getRequestDispatcher("yanzheng.jsp").forward(req,resp);
    }
}
}

3.總結:上述程式碼旨在校驗圖片驗證碼的效果,沒有考慮其他實際情況,尚有改進之處,例如資料庫查詢是否有此使用者名稱,使用者密碼等,同時判斷驗證碼是否正確,正確則註冊成功,否則顯示重新獲取驗證碼,重新註冊。