后台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