用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()方法中编写代码实现生成图片验证码:
分为如下步骤:
-
定义图像数据缓冲区(BufferedImage);
-
创建图片对象;
-
创建绘制工具(Graphics);
-
生成随机数,存入到session中;
-
使用Graphics绘制图形;
-
将验证码通过图像输出流(ImageIO)输出到客户端;
-
最后输入验证码地址即可访问单验证码。
代码如下:
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编的字符串验证码问题的主要内容,如果未能解决你的问题,请参考以下文章