java网页验证码实现

后台servlet+前台JSP。

后台:VerifyCode.java

package com.chenn;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class VerifyCode extends HttpServlet{
	
	//验证码图片宽度,设置初始值只是保守起见,这些值还是要从web.xml配置文件中得到的
	private int width = 100;
	//验证码图片高度
	private int height = 30;
	//验证码字符个数
	private int codeCount = 4;
	//字体高度
	private int fontHeight;
	//第一个字符的X轴值,因为后面的字符坐标依次递增,所以它们的X轴值是codeX的倍数
	private int codeX;
	//验证字符的Y轴值,因为并行所以值一样
	private int codeY;
	//字符允许出现的序列值
	char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',     
            'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',     
            'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
	//初始化图片属性
	public void init() throws ServletException{
		//从web.xml中获取初始信息
		//整张图片的宽度
		String strWidth = this.getInitParameter("width");
		//整张图片的高度 
		String strHeight = this.getInitParameter("height");
		//字符个数
		String strCodeCount = this.getInitParameter("codeCount");
		//将配置的信息转换成数值
		try {
			if(strWidth != null && strWidth.length() != 0){
				width = Integer.parseInt(strWidth);
			}
			if(strHeight != null && strHeight.length() != 0){
				height = Integer.parseInt(strHeight);
			}
			if(strCodeCount != null && strCodeCount.length() != 0){
				codeCount = Integer.parseInt(strCodeCount);
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
        //width-4 除去左右多余的位置,使验证码更加集中显示,减得越多越集中。  
        //codeCount+1     //等比分配显示的宽度,包括左右两边的空格  
		//codeX = width/(codeCount+1);
        codeX = (width-4) / (codeCount+1);  
        //height - 10 集中显示验证码
        fontHeight = height - 10;
        codeY = height - 7;
	}
	//随机生成四位数字,并生成图片输出到servlet输出流中
	protected void service(HttpServletRequest request,HttpServletResponse response) throws ServletException,java.io.IOException{
		//定义图像buffer
		BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		Graphics2D gb = buffImg.createGraphics();
		//创建一个随机数生成器类
		Random random = new Random();
		//将图像填充为橘黄色
		gb.setColor(Color.ORANGE);
		gb.fillRect(0, 0, width, height);
		//创建字体,字体大小应该根据图片的高度来定
		Font font = new Font("Fixedsys", Font.PLAIN, fontHeight);
		//设置字体
		gb.setFont(font);
		//先设置颜色为黑色
		gb.setColor(Color.BLACK);
		//再画边框,
		gb.drawRect(0, 0, width-1, height-1);
		//随机产生16条干扰线,使图像中的认证码不易被其他程序探测到
		gb.setColor(Color.gray);
		for(int i = 0; i<16; i++){
			int x = random.nextInt(width);
			int y = random.nextInt(height);
			int x1 = random.nextInt(12);
			int y1 = random.nextInt(12);
			gb.drawLine(x, y, x+x1, y+y1);
		}
		//randomCode用于保存随机产生的验证码,以便用户登陆后进行验证
		StringBuffer randomCode = new StringBuffer();
		//三原色红绿蓝
		int red = 0, green = 0, blue = 0;
		//随机产生验证码
		for(int i = 0; i<codeCount;i++){
			//得到随机产生的验证码数字
			String strRand = String.valueOf(codeSequence[random.nextInt(36)]);
			//产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色都将不一样
			red = random.nextInt(255);
			green = random.nextInt(255);
			blue = random.nextInt(255);
			gb.setColor(new Color(red, green, blue));
			//将随机产生的颜色绘制到图像中
			gb.drawString(strRand, (i+1)*codeX, codeY);
			//将产生的随机数组合在一起
			randomCode.append(strRand);
		}
		//将四个数字的验证码保存到session中
		HttpSession session = request.getSession();
		session.setAttribute("validateCode", randomCode.toString());;
		//禁止图像缓存
		response.setHeader("Pragma", "no-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0);
		
		response.setContentType("image/jpeg");
		//将图像输出到servlet输出流中
		ServletOutputStream sos = response.getOutputStream();
		ImageIO.write(buffImg, "jpeg", sos);
		sos.close();
	}
}
前台:verifyCode.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 content="text/html; charset=ISO-8859-1" http-equiv="Content-Type">
	
  </head>
  
  <body>
    <div>
    	<%
    		String inputCode = request.getParameter("inputCode");
    		String verifyCode = (String)session.getAttribute("validateCode");
    		if(inputCode!=null && verifyCode!=null){
    			out.print("真正的验证码:"+ verifyCode +"<br/>"+"用户输入的验证码:"+ inputCode +"<br/>");
    			inputCode = inputCode.toUpperCase();
    			out.print("你输入的验证码:"+(inputCode.equals(verifyCode)?"正确":"错误")+"!");
    		}
    	%>
    	<form action="verifyCode.jsp">
    	验证码:<input name="inputCode" value=""/>
    	<img src="VerifyCode-test" align="middle" title="看不清请点我"
    	οnclick="javascript:refresh(this);" οnmοuseοver="mouseover(this)"/>
    	<br/>
    	<input name="submit" type="submit" value="提交"/>
    	</form>
    </div>
    <script >
    	function refresh(obj){
    		obj.src = "VerifyCode-test?"+Math.random();
    	}
    	function mouseover(obj){
    		obj.style.cursor = "pointer";
    	}
    </script>
  </body>
</html>

配置文件:web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
      
    <servlet>
    	<servlet-name>VerifyCode</servlet-name>
    	<servlet-class>com.chenn.VerifyCode</servlet-class>
    	<init-param>  
            <param-name>width</param-name>  
            <param-value>120</param-value>  
        </init-param>  
        <init-param>  
            <param-name>height</param-name>  
            <param-value>32</param-value>  
        </init-param>  
        <init-param>  
            <param-name>codeCount</param-name>  
            <param-value>4</param-value>  
        </init-param> 
    </servlet>
    <servlet-mapping>
    	<servlet-name>VerifyCode</servlet-name>
    	<url-pattern>/VerifyCode-test</url-pattern>
    </servlet-mapping>

</web-app>

测试地址:http://localhost:8080/verifyCode/verifyCode.jsp


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值