字母数字混合验证码
package com.alan.code;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
/**
* 验证码工具类
*/
public class CaptcahCode {
/**
* 验证码的生成方法
* @param response
* @return
*/
public static String drawImage(HttpServletResponse response) {
//1、使用stringbuilder类,对字符串进行处理。不用String,因为其赋值后不能改变。
StringBuilder builder = new StringBuilder();
//2、产生随机数,长度为4
for (int i = 0; i < 4; i++) {
builder.append(randomChar());
}
String code = builder.toString();
//3、定义图片的宽度和高度,使用BufferedImage对象。
int width = 120;
int height = 25;
BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR);
//4、获取Graphics2D 绘制对象,开始绘制验证码
Graphics2D g = bi.createGraphics();
//5、定义文字的字体和大小
Font font = new Font("微软雅黑",Font.PLAIN,20);
//6、定义字体的颜色
Color color = new Color(0,0,0);
//设置字体
g.setFont(font);
//设置颜色
g.setColor(color);
//设置背景
g.setBackground(new Color(226,226,240 ));
//开始绘制对象
g.clearRect(0,0,width,height);
//绘制形状,获取矩形对象
FontRenderContext context = g.getFontRenderContext();
Rectangle2D bounds = font.getStringBounds(code,context);
//计算文件的坐标和间距
double x = (width - bounds.getWidth())/2;
double y = (height- bounds.getHeight())/2;
double ascent = bounds.getY();
double baseY = y - ascent;
g.drawString(code,(int)x,(int)baseY);
//结束绘制
g.dispose();
try {
ImageIO.write(bi,"jpg",response.getOutputStream());
//刷新响应流
response.flushBuffer();
} catch (IOException e) {
e.printStackTrace();
}
return code;
}
/**
* 此方法用于用户产生随机字母和数字
* @return
*/
private static char randomChar(){
// 1、定义验证需要的字母和数字
String str = "ZXCVBNMASDFGHJKLQWERTYUIOP0123456789";
//2、定义随机对象
Random random = new Random();
//3、返回随机字符
return str.charAt(random.nextInt(str.length()));
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<img src="code.jsp" id="code">
<a href="javascript:void(0);" onclick="changeCode()" >看不清,请点击</a>
<script>
function changeCode() {
document.getElementById("code").src = "code.jsp?="+new Date().getTime();
}
</script>
</body>
</html>
<%@ page import="com.alan.code.CaptcahCode" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
/**
* 1、清空浏览器缓存。
* 因为浏览器会对网站的资源文件和图像进行记忆存储,如果被浏览器加载过的图片就会记忆起来,记忆以后文件就不会和
* 服务器交互,如果不清空的话可能会造成的问题是:验证刷新以后没有效果。
*/
response.setHeader("pragma","no-cache");
response.setHeader("cache-control","no-cache");
response.setHeader("expires","0");
//2、调用编写的生成验证码的工具,并将其存入session中
String code = CaptcahCode.drawImage(response);
session.setAttribute("code",code);
//3、解决getOutputStream() has already been called for this response异常
out.clear();
out = pageContext.pushBody();
%>
算术验证码
package com.alan.code;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
/**
* 验证码工具类
*/
public class CaptcahCode {
/**
* 验证码的生成方法
* @param response
* @return
*/
public static String drawImage(HttpServletResponse response) {
//1、使用stringbuilder类,对字符串进行处理。不用String,因为其赋值后不能改变。
StringBuilder builder = new StringBuilder();
//2、产生随机数,长度为4
for (int i = 0; i < 4; i++) {
builder.append(randomChar());
}
String code = builder.toString();
//3、定义图片的宽度和高度,使用BufferedImage对象。
int width = 120;
int height = 25;
BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR);
//4、获取Graphics2D 绘制对象,开始绘制验证码
Graphics2D g = bi.createGraphics();
//5、定义文字的字体和大小
Font font = new Font("微软雅黑",Font.PLAIN,20);
//6、定义字体的颜色
Color color = new Color(0,0,0);
//设置字体
g.setFont(font);
//设置颜色
g.setColor(color);
//设置背景
g.setBackground(new Color(226,226,240 ));
//开始绘制对象
g.clearRect(0,0,width,height);
//绘制形状,获取矩形对象
FontRenderContext context = g.getFontRenderContext();
Rectangle2D bounds = font.getStringBounds(code,context);
//计算文件的坐标和间距
double x = (width - bounds.getWidth())/2;
double y = (height- bounds.getHeight())/2;
double ascent = bounds.getY();
double baseY = y - ascent;
g.drawString(code,(int)x,(int)baseY);
//结束绘制
g.dispose();
try {
ImageIO.write(bi,"jpg",response.getOutputStream());
//刷新响应流
response.flushBuffer();
} catch (IOException e) {
e.printStackTrace();
}
return code;
}
/**
* 算术表达式验证码
*
* 1、干扰线的产生
* 2、范围随机颜色、随机数
* @param response
* @return
*/
public static String drawImageVerificate(HttpServletResponse response){
//定义验证码的宽度和高度
int width = 100, height = 30;
//在内存中创建图片
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
//创建图片上下文
Graphics2D g = image.createGraphics();
//产生随机对象,用于算术表达式的数字
Random random = new Random();
//设置背景
g.setColor(getRandomColor(240,250));
//设置字体
g.setFont(new Font("微软雅黑",Font.PLAIN,22));
//开始绘制
g.fillRect(0,0,width,height);
//干扰线的绘制,绘制线条到图片中
g.setColor(getRandomColor(180,230));
for (int i = 0; i < 100; i++) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int x1 = random.nextInt(60);
int y1 = random.nextInt(60);
g.drawLine(x,y,x1,y1);
}
//对算术验证码表达式的拼接
int num1 = (int) (Math.random()*10+1);
int num2 = (int) (Math.random()*10+1);
int operator = random.nextInt(3);
String operatorStr = null;
int result = 0;
switch (operator) {
case 0:
operatorStr = "+";
result = num1+num2;
break;
case 1:
operatorStr = "-";
result = num1-num2;
break;
case 2:
operatorStr = "*";
result = num1*num2;
break;
}
//图片显示的算术文字
String calc = num1 + " "+ operatorStr +" "+num2+" = ?";
//设置随机颜色
g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
//绘制表达式
g.drawString(calc,5,25);
//结束绘制
g.dispose();
//输出图片到页面
try {
ImageIO.write(image,"JPEG",response.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
return String.valueOf(result);
}
/**
* 随机颜色生成
* @param fc
* @param bc
* @return
*/
public static Color getRandomColor(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);
}
/**
* 此方法用于用户产生随机字母和数字
* @return
*/
private static char randomChar(){
// 1、定义验证需要的字母和数字
String str = "ZXCVBNMASDFGHJKLQWERTYUIOP0123456789";
//2、定义随机对象
Random random = new Random();
//3、返回随机字符
return str.charAt(random.nextInt(str.length()));
}
}
使用kcaptcha框架实现验证码功能
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>关于验证码框架之--Kaptcha</title>
</head>
<style>
#code{
height: 30px;
}
</style>
<body>
<form action="submit.action">
<p>验证码:<input type="text" name="kaptcha" id="code" maxlength="4" value="" /><img src="http://localhost:8080/kaptcha.jpg" id="changeCode"/></p>
<!--使用ajax方式,type定义为button类型,而不是submit类型-->
<p><input type="button" value="登陆" id="login"></p>
<div id="result"></div>
</form>
<script src="js/jquery-1.12.4.min.js"></script>
<script>
$(function () {
$("#changeCode").click(function () {
$(this).attr("src","http://localhost:8080/kaptcha.jpg?="+new Date().getTime());
});
//给登陆按钮绑定点击事件
$("#login").click(function () {
//获取用户输入的验证码
var code = $("#code").val();
var params = {"code":code};
$.post("http://localhost:8080/login",params,function (data) {
//alert(data);
if(data == "success"){
$("#result").html("验证码输入正确");
}else{
$("#result").html("验证码输入有误,请重新输入...");
//重新聚焦到input标签
$("#code").val("").focus();
}
});
});
});
</script>
</body>
</html>
package com.alan.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(name = "LoginServlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置编码
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
//获取浏览器输出流对象
PrintWriter out = response.getWriter();
//获取用户传递过来的验证码
String code = request.getParameter("code");
//获取验证码框架产生的验证码,框架会把验证码以常量的方式放在session中
String sessionCode = (String) request.getSession().getAttribute("kcode");
System.out.println(code+"===="+sessionCode);
if(code!=null&&sessionCode!=null){
//用户输入的验证码和服务端生成的验证码一致时,返回success
if(code.equalsIgnoreCase(sessionCode)){
out.print("success");
}else {
out.print("fail");
}
}else {
out.print("fail");
}
out.flush();
out.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 关于kaptcha验证码-->
<servlet>
<servlet-name>Kaptcha</servlet-name>
<servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
<init-param>
<param-name>kaptcha.image.width</param-name>
<param-value>200</param-value>
</init-param>
<init-param>
<param-name>kaptcha.image.height</param-name>
<param-value>50</param-value>
</init-param>
<init-param>
<param-name>kaptcha.textproducer.char.length</param-name>
<param-value>4</param-value>
</init-param>
<init-param>
<param-name>kaptcha.noise.impl</param-name>
<param-value>com.google.code.kaptcha.impl.NoNoise</param-value>
</init-param>
<init-param>
<param-name>kaptcha.obscurificator.impl</param-name>
<param-value>com.google.code.kaptcha.impl.FishEyeGimpy</param-value>
</init-param>
<init-param>
<param-name>kaptcha.session.key</param-name>
<param-value>kcode</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Kaptcha</servlet-name>
<url-pattern>/kaptcha.jpg</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.alan.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
</web-app>
网友评论