验证码是为了防止“黑客”利用暴力破解密码而出现的安全技术。比如如果没有验证码,一般登陆页面就会只有登陆名和密码,若“黑客”知道一个用户名后,就可以做一个程序,在那一直猜密码,(也就是暴力破解密码),可如果有的验证码后,这种暴力破解密码的方式就不行了。
通过学习验证码的生成与使用,做一下笔记
1、新建web工程:
2、验证码的本质是在java代码里,通过java的画笔画出来的。首先在jsp页面中添加img标签,来接收画出来的验证码图片,并且,这个图片的来源,也就是src属性,是一个web请求,本次练习使用的是servlet技术。jsp文件中的代码:
<img title="看不清?点击换一个" src="yanZhengCode.servlet" id="YZcode" /> <p id="next" style="cursor: pointer;">换一张</p>
3、生成验证码的java文件,也就是yanZhengCode.servlet(要在web.xml中进行配置)中的代码:
package com.wang; /** * 生成验证码 * @author HeJW * */ public class YanZheng extends HttpServlet implements Servlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("image/png"); response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); //如果要全是数字,就把字母去掉 //String charNumber = "0123456789abcdefghijklmnopqrstuvwxyz"; String charNumber = "0123456789"; Random r = new Random(); String code = "" + charNumber.charAt(r.nextInt(charNumber.length())) + charNumber.charAt(r.nextInt(charNumber.length())) + charNumber.charAt(r.nextInt(charNumber.length())) + charNumber.charAt(r.nextInt(charNumber.length())); //设置session,方便工程后面使用验证码的值 request.getSession().setAttribute("YanZheng", code); // 生成这么大小的图片 BufferedImage image = new BufferedImage(100, 45, BufferedImage.TYPE_INT_RGB); // 生成画笔 Graphics g = image.getGraphics(); // 把生成的图片背景色为淡灰色的 g.setColor(Color.GRAY.brighter()); g.fillRect(0, 0, image.getWidth(), image.getHeight()); //验证码字符的大小 Font f = new Font("IMPACT", Font.ITALIC, 30); g.setFont(f); for (int i = 0; i < code.length(); i++) { int y = 25; g.setColor(Color.black); g.drawString("" + code.charAt(i), image.getWidth() / code.length()* i, y); } ImageIO.write(image, "png", response.getOutputStream()); } protected void doPost(HttpServletRequest requset, HttpServletResponse response) throws ServletException, IOException { doGet(requset, response); } }
4、此时,在web页面中已经能够显示验证码了,验证码一帮还有一个“换一个”的功能,其实就是让img标签的src属性重新发送一遍,我用的是jquery:
$("#next").click(function() { $('#YZcode')[0].src="<%=basePath%>yanZhengCode.servlet?timestamp="+new Date().getTime(); });
5、我们再来看看验证码的使用:
package com.wang; public class YanZhengTest extends HttpServlet implements Servlet { protected void doGet(HttpServletRequest request, HttpServletResponse response){ HttpSession session = request.getSession(); String yz = (String)request.getParameter("YZtext"); String yzC = (String)session.getAttribute("YanZheng"); //这样每次用完之后都清空一下session,防止验证码session攻击 session.removeAttribute("YanZheng"); if( yz.equals(yzC)){ System.out.println("true"); } else { System.out.println("false"); } try { response.sendRedirect("index.jsp"); } catch (IOException e) { e.printStackTrace(); } } protected void doPost(HttpServletRequest requset, HttpServletResponse response) throws ServletException, IOException { doGet(requset, response); } }
6、全部源码:
web.xml中的配置:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>YanZhengCord</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>Servlet1</servlet-name> <servlet-class>com.wang.YanZheng</servlet-class> </servlet> <servlet-mapping> <servlet-name>Servlet1</servlet-name> <url-pattern>/yanZhengCode.servlet</url-pattern> </servlet-mapping> <servlet> <servlet-name>Servlet2</servlet-name> <servlet-class>com.wang.YanZhengTest</servlet-class> </servlet> <servlet-mapping> <servlet-name>Servlet2</servlet-name> <url-pattern>/yanZhengTest.servlet</url-pattern> </servlet-mapping> </web-app>
index.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>验证码小例子</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> </head> <script type="text/javascript" src="jquery-1.8.2.js"></script> <script type="text/javascript"> $(document).ready(function() { $("#next").click(function() { $('#YZcode')[0].src="<%=basePath%>yanZhengCode.servlet?timestamp="+new Date().getTime(); }); }); </script> <body> <img title="看不清?点击换一个" src="yanZhengCode.servlet" id="YZcode" /> <p id="next" style="cursor: pointer;">换一张</p> <form action="yanZhengTest.servlet" method="post"> 验证码:<input type="text" id="YZtext" name="YZtext"/> <input type="submit"/> </form> </body> </html>
生成验证码:
package com.wang; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; import javax.imageio.ImageIO; import javax.servlet.Servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 生成验证码 * @author HeJW * */ public class YanZheng extends HttpServlet implements Servlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("image/png"); response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); //如果要全是数字,就把字母去掉 //String charNumber = "0123456789abcdefghijklmnopqrstuvwxyz"; String charNumber = "0123456789"; Random r = new Random(); String code = "" + charNumber.charAt(r.nextInt(charNumber.length())) + charNumber.charAt(r.nextInt(charNumber.length())) + charNumber.charAt(r.nextInt(charNumber.length())) + charNumber.charAt(r.nextInt(charNumber.length())); //设置session,方便工程后面使用验证码的值 request.getSession().setAttribute("YanZheng", code); // 生成这么大小的图片 BufferedImage image = new BufferedImage(100, 45, BufferedImage.TYPE_INT_RGB); // 生成画笔 Graphics g = image.getGraphics(); // 把生成的图片背景色为淡灰色的 g.setColor(Color.GRAY.brighter()); g.fillRect(0, 0, image.getWidth(), image.getHeight()); //验证码字符的大小 Font f = new Font("IMPACT", Font.ITALIC, 30); g.setFont(f); for (int i = 0; i < code.length(); i++) { int y = 25; g.setColor(Color.black); g.drawString("" + code.charAt(i), image.getWidth() / code.length()* i, y); } ImageIO.write(image, "png", response.getOutputStream()); } protected void doPost(HttpServletRequest requset, HttpServletResponse response) throws ServletException, IOException { doGet(requset, response); } }
验证码使用:
package com.wang; import java.io.IOException; import javax.servlet.Servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class YanZhengTest extends HttpServlet implements Servlet { protected void doGet(HttpServletRequest request, HttpServletResponse response){ HttpSession session = request.getSession(); String yz = (String)request.getParameter("YZtext"); String yzC = (String)session.getAttribute("YanZheng"); //这样每次用完之后都清空一下session,防止验证码session攻击 session.removeAttribute("YanZheng"); if( yz.equals(yzC)){ System.out.println("true"); } else { System.out.println("false"); } try { response.sendRedirect("index.jsp"); } catch (IOException e) { e.printStackTrace(); } } protected void doPost(HttpServletRequest requset, HttpServletResponse response) throws ServletException, IOException { doGet(requset, response); } }