对初学java实现验证码的详细指导

1、servlet

package com.servlet;



import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.io.*;
import java.util.*;


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 javax.imageio.ImageIO;


public class PictureCheckCode extends HttpServlet {


private static final long serialVersionUID = 1L;


public PictureCheckCode() {
super();
}


public void destroy() {
super.destroy();
}


public void init() throws ServletException {
super.init();
}


/* 该方法主要作用是获得随机生成的颜色 */
public Color getRandColor(int s, int e) {
Random random = new Random();
if (s > 255)
s = 255;
if (e > 255)
e = 255;
int r, g, b;
r = s + random.nextInt(e - s); // 随机生成RGB颜色中的r值
g = s + random.nextInt(e - s); // 随机生成RGB颜色中的g值
b = s + random.nextInt(e - s); // 随机生成RGB颜色中的b值
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 = 86, height = 22; // 指定生成验证码的宽度和高度
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB); // 创建BufferedImage对象,其作用相当于一图片
Graphics g = image.getGraphics(); // 创建Graphics对象,其作用相当于画笔
Graphics2D g2d = (Graphics2D) g; // 创建Grapchics2D对象
Random random = new Random();
Font mfont = new Font("楷体", Font.BOLD, 16); // 定义字体样式
g.setColor(getRandColor(200, 250));
g.fillRect(0, 0, width, height); // 绘制背景
g.setFont(mfont); // 设置字体
g.setColor(getRandColor(180, 200));


// 绘制100条颜色和位置全部为随机产生的线条,该线条为2f
for (int i = 0; i < 100; i++) {
int x = random.nextInt(width - 1);
int y = random.nextInt(height - 1);
int x1 = random.nextInt(6) + 1;
int y1 = random.nextInt(12) + 1;
BasicStroke bs = new BasicStroke(2f, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_BEVEL); // 定制线条样式
Line2D line = new Line2D.Double(x, y, x + x1, y + y1);
g2d.setStroke(bs);
g2d.draw(line); // 绘制直线
}
// 输出由英文,数字,和中文随机组成的验证文字,具体的组合方式根据生成随机数确定。
String sRand = "";
String ctmp = "";
int itmp = 0;
// 制定输出的验证码为四位
for (int i = 0; i < 4; i++) {
switch (random.nextInt(3)) {
case 1: // 生成A-Z的字母
itmp = random.nextInt(26) + 65;
ctmp = String.valueOf((char) itmp);
break;
case 2: // 生成汉字
String[] rBase = { "0", "1", "2", "3", "4", "5", "6", "7", "8",
"9", "a", "b", "c", "d", "e", "f" };
// 生成第一位区码
int r1 = random.nextInt(3) + 11;
String str_r1 = rBase[r1];
// 生成第二位区码
int r2;
if (r1 == 13) {
r2 = random.nextInt(7);
} else {
r2 = random.nextInt(16);
}
String str_r2 = rBase[r2];
// 生成第一位位码
int r3 = random.nextInt(6) + 10;
String str_r3 = rBase[r3];
// 生成第二位位码
int r4;
if (r3 == 10) {
r4 = random.nextInt(15) + 1;
} else if (r3 == 15) {
r4 = random.nextInt(15);
} else {
r4 = random.nextInt(16);
}
String str_r4 = rBase[r4];
// 将生成的机内码转换为汉字
byte[] bytes = new byte[2];
// 将生成的区码保存到字节数组的第一个元素中
String str_12 = str_r1 + str_r2;
int tempLow = Integer.parseInt(str_12, 16);
bytes[0] = (byte) tempLow;
// 将生成的位码保存到字节数组的第二个元素中
String str_34 = str_r3 + str_r4;
int tempHigh = Integer.parseInt(str_34, 16);
bytes[1] = (byte) tempHigh;
ctmp = new String(bytes);
break;
default:
itmp = random.nextInt(10) + 48;
ctmp = String.valueOf((char) itmp);
break;
}
sRand += ctmp;
Color color = new Color(20 + random.nextInt(110),
20 + random.nextInt(110), random.nextInt(110));
g.setColor(color);
// 将生成的随机数进行随机缩放并旋转制定角度 PS.建议不要对文字进行缩放与旋转,因为这样图片可能不正常显示
/* 将文字旋转制定角度 */
Graphics2D g2d_word = (Graphics2D) g;
AffineTransform trans = new AffineTransform();
trans.rotate((45) * 3.14 / 180, 15 * i + 8, 7);
/* 缩放文字 */
float scaleSize = random.nextFloat() + 0.8f;
if (scaleSize > 1f)
scaleSize = 1f;
trans.scale(scaleSize, scaleSize);
g2d_word.setTransform(trans);
g.drawString(ctmp, 15 * i + 18, 14);
}
HttpSession session = request.getSession(true);
session.setAttribute("randCheckCode", sRand);
g.dispose(); // 释放g所占用的系统资源
ImageIO.write(image, "JPEG", response.getOutputStream()); // 输出图片
}

}


2、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">
<display-name></display-name>
<servlet>
<description>输出验证码</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>PictureCheckCode</servlet-name>
<servlet-class>com.servlet.PictureCheckCode</servlet-class>
</servlet>


<servlet-mapping>
<servlet-name>PictureCheckCode</servlet-name>
<url-pattern>/PictureCheckCode</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>


3、index.jsp页面

<%@ page language="java" import="java.util.*" pageEncoding="gbk"%>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>验证码</title>
<script language="javascript">
function myReload() {
document.getElementById("CreateCheckCode").src = document
.getElementById("CreateCheckCode").src
+ "?nocache=" + new Date().getTime();
}
</script>
</head>


<body>
<form action="Check.jsp" method="post">
<input name="checkCode" type="text" id="checkCode" title="验证码区分大小写"
size="8" ,maxlength="4" />
<img src="PictureCheckCode" id="CreateCheckCode" align="middle">
<a href="" οnclick="myReload()">&nbsp;看不清,换一个</a>
<input type="submit" value="提交" />
</form>
</body>
</html>

4、Check.jsp页面

<%@ page language="java" import="java.util.*" pageEncoding="gbk"%>
<html>
  <head>
    <title>验证码校验</title>
  </head>
  
  <body>
    <%
    String checkcode=request.getParameter("checkCode");
    if(checkcode.equals("")||checkcode==null){
    out.print("<script>alert('请输入验证码');window.location.href('index.jsp')</script>");
    }else{
    if(!checkcode.equalsIgnoreCase((String)session.getAttribute("randCheckCode"))){
    out.print("<script>alert('验证码不正确,请重新输入');history.back(-1);</script>");
    }else{
    out.print("登录成功");
    }
    }
     %>
  </body>

</html>

5、目录参照

6、结果


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值