验证码实现与验证
1.最基本的实现验证码java代码
package yanZhengma; import java.awt.Color; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.OutputStream; import java.util.Random; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGImageDecoder; import com.sun.image.codec.jpeg.JPEGImageEncoder; public class Getyzm extends HttpServlet { private static final long serialVersionUID = 1L; protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("service......."); /*1.设置服务器返回文件的格式为jpg格式的图片 *常见的有 text/html 或者text/xml * */ response.setContentType("image/jpeg"); /*2.画图 *bufferedImage:内存映像对象 * */ BufferedImage bufferedImage = new BufferedImage(60,20,BufferedImage.TYPE_INT_RGB); Random random = new Random(); //获得画笔 Graphics graphics = bufferedImage.getGraphics(); //设置背景颜色 graphics.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255))); //填充背景颜色 graphics.fillRect(0, 0, 60, 20); //设置前景颜色 graphics.setColor(new Color(0,0,0)); //生产随机数 String number =String.valueOf(random.nextInt(99999)); HttpSession session = request.getSession(); session.setAttribute("yanzhima", number); //将数字画在图片上 graphics.drawString(number, 5, 15); /*3.压缩图片以输出 * 获得字节输出流 * 因为要输出的是图形压缩之后的字节数组,所以,不能用PrintWriter * */ OutputStream oStream = response.getOutputStream() ; //将图片压缩输出 JPEGImageEncoder jEncoder = JPEGCodec.createJPEGEncoder(oStream); jEncoder.encode(bufferedImage); } }
jsp页面内容
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!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=ISO-8859-1"> <title>Insert title here</title> <script type="text/javascript"> function test(){ document.getElementById('img1').src='Getyzm?'+Math.random(); } function verify(){ window.location.href= "result.jsp"; } </script> </head> <body> Hello , <img alt="" src="Getyzm" id="img1"> <!-- 注意src需要与servlet的名字一样 --> <a href="javascript:;" onclick="test()">change picture</a> <input type="button" value="verify" onclick="verify()"/> </body> </html>
在result界面可以获取验证码内容进行比较即可
2.复杂且比较完善的验证码实现与验证
package com.netcloud.verify; /*1.loginin界面调用验证码,刷新验证码 * 2.regist页面,点击验证即可验证验证码,跳转testVerify界面 * * */ 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.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class VerifyServlet extends HttpServlet { private static final long serialVersionUID = 1L; // 设置图形验证码中字符串的字体和大小 private Font myFont = new Font("Arial Black", Font.PLAIN, 16); public void init() throws ServletException { super.init(); } // 生成随机颜色 Color getRandColor(int fc, int bc) { Random random = new Random(); if (fc > 255) fc = 255; if (bc > 255) bc = 255; int r = fc + random.nextInt(bc - fc); int g = fc + random.nextInt(bc - fc); int b = fc + random.nextInt(bc - fc); return new Color(r, g, b); } @Override public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 阻止生成的页面内容被缓存,保证每次重新生成随机验证码 response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); response.setContentType("image/jpeg"); // 指定图形验证码图片的大小 int width = 100, height = 20; // 生成一张新图片 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 在图片中绘制内容 Graphics g = image.getGraphics(); Random random = new Random(); g.setColor(getRandColor(200, 250)); g.fillRect(1, 1, width - 1, height - 1); g.setColor(new Color(102, 102, 102)); g.drawRect(0, 0, width - 1, height - 1); g.setFont(myFont); // 随机生成线条,让图片看起来更加杂乱 g.setColor(getRandColor(160, 200)); for (int i = 0; i < 155; i++) { int x = random.nextInt(width - 1);// 起点的x坐标 int y = random.nextInt(height - 1);// 起点的y坐标 int x1 = random.nextInt(6) + 1;// x轴偏移量 int y1 = random.nextInt(12) + 1;// y轴偏移量 g.drawLine(x, y, x + x1, y + y1); } // 随机生成线条,让图片看起来更加杂乱 for (int i = 0; i < 70; i++) { int x = random.nextInt(width - 1); int y = random.nextInt(height - 1); int x1 = random.nextInt(12) + 1; int y1 = random.nextInt(6) + 1; g.drawLine(x, y, x - x1, y - y1); } // 该变量用来保存系统生成的随机字符串 String sRand = ""; for (int i = 0; i < 6; i++) { // 取得一个随机字符 String tmp = getRandomChar(); sRand += tmp; // 将系统生成的随机字符添加到图形验证码图片上 g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110))); g.drawString(tmp, 15 * i + 10, 15); } // 取得用户Session HttpSession session = request.getSession(true); // 将系统生成的图形验证码添加 session.setAttribute("rand", sRand); g.dispose(); // 输出图形验证码图片 ImageIO.write(image, "JPEG", response.getOutputStream()); } // 随机生成一个字符 private String getRandomChar() { int rand = (int) Math.round(Math.random() * 2);// 将0~2的小数四舍五入生成整数 long itmp = 0; char ctmp = ' '; // 根据rand的值来决定是生成一个大写字母、小写字母和数字 switch (rand) { // 生成大写字母的情形 case 1: itmp = Math.round(Math.random() * 25 + 65); ctmp = (char) itmp; return String.valueOf(ctmp); // 生成小写字母 case 2: itmp = Math.round(Math.random() * 25 + 97); ctmp = (char) itmp; return String.valueOf(ctmp); // 生成数字 default: itmp = Math.round(Math.random() * 9); return String.valueOf(itmp); } } }
然后使用在注册界面
<%@page import="java.io.PrintWriter"%> <%@ 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>注册页面</title> <script type="text/javascript" src="js/jquery.js" ></script> <script type="text/javascript"> $(function(){ document.getElementById("authImg").src="VerifyServlet?now="+new Date();//使用时间作为参数避免浏览器从缓存取图片 }); //刷新验证码 function refresh() { document.getElementById("authImg").src="VerifyServlet?now="+new Date();//使用时间作为参数避免浏览器从缓存取图片 } </script> </head> <body> <form action="testVerify.jsp" method="post"> <table> <caption><h2>用户注册</h2></caption> <tr> <td>用 户 名:</td><td><input type="text" name="username" id="username"/></td> </tr> <tr> <td>密 码:</td><td><input type="text" name="password" id="password"/> </td> </tr> <tr> <td>确认密码:</td><td><input type="text" name="chkpassword"/> </td> </tr> <tr> <td>Email:</td><td><input type="text" name="email"/> </td> </tr> <tr> <td>验证码:</td><td valign="bottom"><input type="text" name="vercode" size="10" id="vercode"/> <img alt="" src="authImg" id="authImg" align="absmiddle"><a href="#" href="#" onclick="refresh()"><span style="font-size:12px" style="font-size:12px">刷新验证码</span></a></td> </tr> <tr> <td colspan="2"><input type="submit" value="提交" id="testVerify"/><input type="reset" value="重填"/></td> </tr> </table> </form> </body> </html>
testVerify.jsp页面数据如下
<%@ 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> </head> <body> <% String rand = (String)session.getAttribute("rand"); String input = request.getParameter("vercode"); if(rand.equalsIgnoreCase(input)){ out.print("<script>alert('验证通过!');</script>"); } else{ out.print("<script>alert('请输入正确的验证码!');location.href='regist.jsp';</script>"); } %> </body> </html>
即可验证输入的验证码是否正确