当然可以使用框架了。本文是介绍如何手写一个简单的验证码.
字母数字混合验证码:
首先先处理生成字母和数字:
/**
* 产生随机数字和字母
* @return
*/
private static char randomChar(){
//定义验证需要的字母和数字
String str = "QWERTYUIOPASDFGHJKLZXCVBNM0123456789";
Random random = new Random();
return str.charAt(random.nextInt(str.length()));
}
正如你所看到的,很简单。
然后就是验证码的绘制了:
public static String drawImage(HttpServletResponse response){
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 4; i++) {
builder.append(randomChar());
}
String code = builder.toString();
//定义图片的宽度和高度
int width = 120;
int height = 25;
//建立bufferedImage对象,制定图片的长度和宽度以及色彩
BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR);
//获取Graphics2D,开始绘制验证码
Graphics2D g = bi.createGraphics();
Font font = new Font("微软雅黑",Font.PLAIN,20);
Color color = new Color(255, 255, 255);
g.setFont(font);
g.setColor(color);
g.setBackground(new Color(41,214,204));
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;
}
完整代码:
package com.verificationcode.yinlei;
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){
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 4; i++) {
builder.append(randomChar());
}
String code = builder.toString();
//定义图片的宽度和高度
int width = 120;
int height = 25;
//建立bufferedImage对象,制定图片的长度和宽度以及色彩
BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR);
//获取Graphics2D,开始绘制验证码
Graphics2D g = bi.createGraphics();
Font font = new Font("微软雅黑",Font.PLAIN,20);
Color color = new Color(255, 255, 255);
g.setFont(font);
g.setColor(color);
g.setBackground(new Color(41,214,204));
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(){
//定义验证需要的字母和数字
String str = "QWERTYUIOPASDFGHJKLZXCVBNM0123456789";
Random random = new Random();
return str.charAt(random.nextInt(str.length()));
}
}
code.jsp:
<%@ page import="com.verificationcode.yinlei.CaptcahCode" %><%--
Created by IntelliJ IDEA.
User: 10991
Date: 2019/11/2
Time: 11:19
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
//1.清空浏览器的缓存
response.setHeader("pragma","no-cache");
response.setHeader("cache-control","no-cache");
response.setHeader("expires","0");
//调用生成验证码的工具类
String code = CaptcahCode.drawImage(response);
session.setAttribute("code",code);
out.clear();
out = pageContext.pushBody();
%>
</body>
</html>
index.jsp:
<%@ page import="com.verificationcode.yinlei.CaptcahCode" %><%--
Created by IntelliJ IDEA.
User: 10991
Date: 2019/11/2
Time: 10:53
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<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?d="+new Date().getTime();
}
</script>
</body>
</html>
算术验证码:
/**
* 算术表达式验证码
* 干扰线的产生
* 范围随机颜色、随机数
* @param response
* @return
*/
public static String drawImageVerificate(HttpServletResponse response){
int width = 100;
int 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 fuhao = random.nextInt(4);//产生一个[0,3]之间的随机整数
String fuhaostr = null;
int result =0;
switch (fuhao){
case 0:
fuhaostr = "+";
result=num1+num2;
break;
case 1:
fuhaostr = "-";
result=num1-num2;
break;
case 2:
fuhaostr = "*";
result=num1*num2;
break;
case 3:
fuhaostr = "/";
result=num1/num2;
break;
}
String calc = num1+" "+fuhaostr+" "+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());
return String.valueOf(result);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 范围随机颜色
* @param fc
* @param bc
* @return
*/
public static Color getRandomColor(int fc, int bc){
Random random = new Random();
//随机颜色,了解颜色Color(red,green,blue),rgb3元色 0 - 255
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);
}
工具类源代码:
package com.verificationcode.yinlei;
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){
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 4; i++) {
builder.append(randomChar());
}
String code = builder.toString();
//定义图片的宽度和高度
int width = 120;
int height = 25;
//建立bufferedImage对象,制定图片的长度和宽度以及色彩
BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR);
//获取Graphics2D,开始绘制验证码
Graphics2D g = bi.createGraphics();
Font font = new Font("微软雅黑",Font.PLAIN,20);
Color color = new Color(255, 255, 255);
g.setFont(font);
g.setColor(color);
g.setBackground(new Color(41,214,204));
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;
}
/**
* 算术表达式验证码
* 干扰线的产生
* 范围随机颜色、随机数
* @param response
* @return
*/
public static String drawImageVerificate(HttpServletResponse response){
int width = 100;
int 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 fuhao = random.nextInt(4);//产生一个[0,3]之间的随机整数
String fuhaostr = null;
int result =0;
switch (fuhao){
case 0:
fuhaostr = "+";
result=num1+num2;
break;
case 1:
fuhaostr = "-";
result=num1-num2;
break;
case 2:
fuhaostr = "*";
result=num1*num2;
break;
case 3:
fuhaostr = "/";
result=num1/num2;
break;
}
String calc = num1+" "+fuhaostr+" "+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());
return String.valueOf(result);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 范围随机颜色
* @param fc
* @param bc
* @return
*/
public static Color getRandomColor(int fc, int bc){
Random random = new Random();
//随机颜色,了解颜色Color(red,green,blue),rgb3元色 0 - 255
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(){
//定义验证需要的字母和数字
String str = "QWERTYUIOPASDFGHJKLZXCVBNM0123456789";
Random random = new Random();
return str.charAt(random.nextInt(str.length()));
}
}