用servlet编的字符串验证码问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用servlet编的字符串验证码问题相关的知识,希望对你有一定的参考价值。

编写一个Servlet,要求:自动生成4位数字的随机验证码,并将生成的验证码字符串保存到会话对象中,向浏览器发送纯文本格式的验证码字符串。这三个我都写在一个servlet里了但是运行的时候由于先生成了一个验证码,再传给servlet又生成了一个码,两个码始终不一致,知道错误不知道怎么解决- -请教高手们

参考技术A 我有个产生验证码的servlet你可以参考一下,我测试没问题。我在最后还给了一个JSP页面给你参考。 import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
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 CheckCodeServlet extends HttpServlet
private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
doPost(request, response);
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException

//设置长宽
int width = 120;
int height = 60;
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_3BYTE_BGR);
Graphics g = image.getGraphics();
Random random = new Random();
//颜色
g.setColor(getRandColor(200, 250));
g.fillRect(0, 0, width, height);
g.setColor(getRandColor(0, 255));
g.drawRect(0, 0, width - 1, height - 1);
g.setColor(getRandColor(160, 200));
for (int i = 0; i < 8; i++)
int x = random.nextInt(width);
int y = random.nextInt(height);
int x1 = random.nextInt(width);
int y1 = random.nextInt(height);
g.drawLine(x, y, x1, y1);

g.setColor(getRandColor(160, 200));
for (int i = 0; i < 100; i++)
int x = random.nextInt(width);
int y = random.nextInt(height);
g.drawLine(x, y, x, y);

Font font = new Font("Times New Roman", Font.ITALIC, 38);
g.setFont(font);
int length = 4;//验证码位数
String s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
String sRand = ""; g.setColor(new Color(20 + random.nextInt(110),
20 + random.nextInt(110), 20 + random.nextInt(110)));
for (int i = 0; i < length; i++)
String ch = String.valueOf(s.charAt(random.nextInt(s.length())));
sRand += ch;
g.drawString(ch, 22 * i + 12, (random.nextInt(5) - 2) * i + 40);
//验证码放入session中,然后在需要的时候验证(判断session中的验证码是否equals输入的验证码)
HttpSession session = request.getSession();
session.setAttribute("checkCode", sRand);
g.dispose(); //消除缓存
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
response.setContentType("image/jpeg"); //输出图片
ServletOutputStream sos = response.getOutputStream();
ImageIO.write(image, "jpeg", sos);
sos.flush();
sos.close();

//随机颜色
private Color getRandColor(int lower, int upper)
Random random = new Random();
if (upper > 255)
upper = 255;
if (upper < 1)
upper = 1;
if (lower < 1)
lower = 1;
if (lower > 255)
lower = 255;
int r = lower + random.nextInt(upper - lower);
int g = lower + random.nextInt(upper - lower);
int b = lower + random.nextInt(upper - lower);
return new Color(r, g, b);


/*<%@ page language="java" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" " http://www.w3.org/TR/html4/loose.dtd">
<html>
<head> <title>验证码</title>
<script type="text/javascript" language="javascript">
function changeImg()
var a=document.getElementById("mySpan");
a.innerHTML='<img align="middle" src="CheckCodeServlet"/> <a href="#" onclick="changeImg();">看不清楚,换一张</a>';

</script>
</head> <%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<body>
<span id="mySpan"><img align="middle" src="CheckCodeServlet" /><a
href="#" onclick="changeImg();">看不清楚,换一张</a> </span>
</body> </html>
注意配置servlet路径时要配置成 /CheckCodeServlet ,因为页面的src路径是CheckCodeServlet*/

Javaweb 响应——生成验证码

使用Servlet生成验证码

如何使用Servlet生成验证码

在Java中我们可以在Web项目中使用Servlet来生成验证码,流程是:前端请求验证码servlet对应的地址,后端servlet收到请求,生成一串字符作为验证码,存入到Session中,最后将验证码作为一张图片返回给前端。前端填写了验证码提交到服务器来验证。

我们看一个示例,你也可以根据这个示例在右侧编辑器中一步一步实现验证码的功能。

项目和servlet已经创建好了,我们首先在web.xml文件中注册servlet。

步骤

在servlet的doGet()方法中编写代码实现生成图片验证码:

分为如下步骤:

  1. 定义图像数据缓冲区(BufferedImage);

  2. 创建图片对象;

  3. 创建绘制工具(Graphics);

  4. 生成随机数,存入到session中;

  5. 使用Graphics绘制图形;

  6. 将验证码通过图像输出流(ImageIO)输出到客户端;

  7. 最后输入验证码地址即可访问单验证码。

代码如下:

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 使用验证码的步骤
    // 定义图片的宽高
    int height = 20;
    int width = 60;
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    // 绘图工具
    Graphics graphics = image.getGraphics();
    // 绘制矩形
    graphics.setColor(getRandColor());
    // 绘制矩形背景 前两个参数 是 x y的坐标
    graphics.fillRect(0, 0, width, height);
    // 设置文字的颜色 为白色
    graphics.setColor(Color.WHITE);
    String yzm = "";
    // 生成四个随机数字并且画在图片上
    for (int i = 1; i <= 4; i++) {
        // 生成随机数字并且显示到页面上
        int number = new Random().nextInt(10);
        yzm += number;
        graphics.drawString(number + "", 10 * i, 10);
    }
    // 将验证码放入Httpsession中
    HttpSession session = req.getSession();
    session.setAttribute("sessionYzm", yzm);
    // 将验证码图片输出到客户端
    ImageIO.write(image, "jpg", resp.getOutputStream());
}
// 获取随机颜色
private Color getRandColor() {
    int red = new Random().nextInt(255);
    int green = new Random().nextInt(255);
    int blue = new Random().nextInt(255);
    return new Color(red, green, blue);
}

效果如下:
在这里插入图片描述

验证码案例:

案例1:

效果

在这里插入图片描述

html

html中,没点击一次img 标签(即验证码图片)就会请求一次servlet得到一个响应,重新绘制验证码图案。

<div class="verify">
	<input name="check" type="text" placeholder="请输入验证码" autocomplete="off">
	<span><img src="checkCode" alt="" onclick="changeCheckCode(this)"></span>
	<script type="text/javascript">
		//图片点击事件
		function changeCheckCode(img) {
			img.src="checkCode?"+new Date().getTime();
			// console.log	(new Date().getTime());
			// 时间戳
		}

	</script>
</div>

servlet

package cn.itcast.travel.web.servlet;

import javax.imageio.ImageIO;
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.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

/**
 * 验证码
 */
@WebServlet("/checkCode")
public class CheckCodeServlet extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
		
		//服务器通知浏览器不要缓存
		response.setHeader("pragma","no-cache");
		response.setHeader("cache-control","no-cache");
		response.setHeader("expires","0");
		
		//在内存中创建一个长80,宽30的图片,默认黑色背景
		//参数一:长
		//参数二:宽
		//参数三:颜色
		int width = 80;
		int height = 30;
		BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
		
		//获取画笔
		Graphics g = image.getGraphics();
		//设置画笔颜色为灰色
		g.setColor(Color.GRAY);
		//填充图片
		g.fillRect(0,0, width,height);
		
		//产生4个随机验证码,12Ey
		String checkCode = getCheckCode();
		//将验证码放入HttpSession中
		request.getSession().setAttribute("CHECKCODE_SERVER",checkCode);
		
		//设置画笔颜色为黄色
		g.setColor(Color.YELLOW);
		//设置字体的小大
		g.setFont(new Font("黑体",Font.BOLD,24));
		//向图片上写入验证码
		g.drawString(checkCode,15,25);
		
		//将内存中的图片输出到浏览器
		//参数一:图片对象
		//参数二:图片的格式,如PNG,JPG,GIF
		//参数三:图片输出到哪里去
		ImageIO.write(image,"PNG",response.getOutputStream());
	}
	/**
	 * 产生4位随机字符串 
	 */
	private String getCheckCode() {
		String base = "0123456789ABCDEFGabcdefg";
		int size = base.length();
		Random r = new Random();
		StringBuffer sb = new StringBuffer();
		for(int i=1;i<=4;i++){
			//产生0到size-1的随机值
			int index = r.nextInt(size);
			//在base字符串中获取下标为index的字符
			char c = base.charAt(index);
			//将c放入到StringBuffer中去
			sb.append(c);
		}
		return sb.toString();
	}
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doGet(request,response);
	}
}




案例2:

效果

在这里插入图片描述

servlet

public class ResponseDemo3 extends HttpServlet {

    /**
     * 输出图片
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        int width = 200;
        int height = 35;
        /**
         * 实现步骤:
         * 	1.创建图像内存对象
         *  2.拿到画笔
         *  3.设置颜色,画矩形边框
         *  4.设置颜色,填充矩形
         *  5.设置颜色,画干扰线
         *  6.设置颜色,画验证码
         *  7.把内存图像输出到浏览器上
         */
        //创建内存图像
        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);//参数:宽度,高度 (指的都是像素),使用的格式(RGB)
        Graphics g = image.getGraphics();//画笔就一根

        //设置颜色
        g.setColor(Color.BLUE);
        //画边框
        g.drawRect(0, 0, width, height);

        //设置颜色
        g.setColor(Color.GRAY);
        //填充矩形
        g.fillRect(1, 1, width-2, height-2);

        //设置颜色
        g.setColor(Color.WHITE);
        //拿随机数对象
        Random r = new Random();
        //画干扰线 10条
        for(int i=0;i<10;i++){
            g.drawLine(r.nextInt(width), r.nextInt(height),r.nextInt(width), r.nextInt(height));
        }

        //设置颜色
        g.setColor(Color.RED);
        //改变字体大小
        Font font = new Font("宋体", Font.BOLD,30);//参数:1字体名称。2.字体样式 3.字体大小
        g.setFont(font);//设置字体
        //画验证码	4个
        int x = 35;//第一个数的横坐标是35像素
        for(int i=0;i<4;i++){
            //r.nextInt(10)+""这种写法效率是十分低的
            g.drawString(String.valueOf(r.nextInt(10)), x, 25);
            x+=35;
        }

        //输出到浏览器上
        //参数: 1.内存对象。2.输出的图片格式。3.使用的输出流
        ImageIO.write(image, "jpg", response.getOutputStream());
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

以上是关于用servlet编的字符串验证码问题的主要内容,如果未能解决你的问题,请参考以下文章

JAVA图片验证码(转自“云在青山”)

用servlet怎么实现验证码

IT兄弟连 JavaWeb教程 jQuery对AJAX的支持经典案例

kaptcha 验证码组件使用

自己动手用写简单的验证码(JAVA)

地球人终于要消灭验证码了