基本上和前面的那个差不多,但是稍微复杂一点
CaptcahCode.java
package com.imooc.code;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
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 {
/**
* 算术表达式验证码
* 1、干扰线的产生
* 2、范围随机颜色,随机数
* @param response
* @return
*/
public static String drawImageVericate(HttpServletResponse response){
//定义验证码的宽度和高度
int width = 100,height = 30;
//在内存中创建图片
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR);
//创建图片的上下文
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);
//使用drawLine画线
g.drawLine(x,y,x1,y1);
}
//开始进行对算输验证码表达式的拼接
//这里注意,math的括号要包住后面的*10,不然会先计算(int)Math.random(),因为这个值介于0,1,一直都会是0
int num1 = (int)(Math.random()*10) +1;
int num2 = (int)(Math.random()*10) +1;
System.out.println(num1);
System.out.println(num2);
//符号,产生一个[0,2]之间的随机数,0,1,2用于表示加减乘
int symbol = random.nextInt(3);
String symbolstr = "";
int result =0;
switch (symbol){
case 0:symbolstr = "+";result = num1 + num2;break;
case 1:symbolstr = "-";result = num1 - num2;break;
case 2:symbolstr = "*";result = num1 * num2;break;
}
//拼接计算表达式,用于图片显示
String calc = num1 + " " + symbolstr +" "+num2 + "=" +"?";
//设置随机颜色
g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
//绘制表达式
g.drawString(calc,5,23);
//结束绘制
g.dispose();
try {
//输出图片到页面
ImageIO.write(image,"jpg",response.getOutputStream());
return String.valueOf(result);
}catch (Exception ex){
ex.printStackTrace();
return null;
}
}
/**
* 获取随机颜色
* @param fc
* @param bc
* @return
*/
public static Color getRandomColor(int fc,int bc){
Random random = new Random();
//随机颜色,颜色的组成有三个参数,red,green和blue
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);
Color random_color = new Color(r,g,b);
return random_color;
}
}
code.jsp
<%@ page import="com.imooc.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、调用编写的生成验证码的工具
String code = CaptcahCode.drawImageVericate(response);
session.setAttribute("code",code);
//我这里遇到一个问题,在firefox和ie没问题,用chrome就打不开,而且还报错ERR_INCOMPLETE_CHUNKED_ENCODING,然后执行下面的第三步操作,chrome就可以了...,
//3、解决getOutputStream异常问题,但是不知道为啥这么些
out.clear();
out = pageContext.pushBody();
%>
index.jsp
<%--
Created by IntelliJ IDEA.
User: msi
Date: 2020/7/4
Time: 8:47
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" alt="oops" id = "code">
<a href="javascript:void(0);" onclick="changeCode()">换一张</a>
<script>
function changeCode() {
//这里加?time=是为了避免浏览器缓存而导致加载不出验证码
document.getElementById("code").src = "code.jsp"+"?time="+new Date().getTime();
}
</script>
</body>
</html>