1.验证码无非就是点击一个链接可以产生或更改验证码,并且输入验证码可以完成验证
2.前台界面
`
<h1>验证码</h1>
<a href="javascript:void(0)" onclick="setVerifyCode(this)">看不清,换一张</a>
<img alt="" src=""id="img1">
<span id="sp1">${sessionScope.verifyCode }</span>
<button onclick="getVerifyCodeValue()">获取验证码值</button>
<%=request.getSession().getAttribute("verifyCode") %>
<input type="text" name="verifyCode" id="verifyCode">
<button onclick="check()">检验</button>
<span id="sp3"></span>
<span id="sp4">${verifyCode }</span>
`
3.ajax接受前台发送的请求并转发给servlet
//响应目标函数
var xmlrequest;
function createXMLHttpRequest()
{
if(window.ActiveXObject)
{
xmlrequest=new ActionXObject("Miscrosoft.XMLHTTP");
}
else
{
xmlrequest=new XMLHttpRequest();
}
}
function setVerifyCode(o)
{
createXMLHttpRequest();
if(xmlrequest)
{
var req="/xiaoneinew/verifyCode2";
// window.alert(req);
xmlrequest.open("get",req,true);
//指定处理结果的函数
xmlrequest.onreadystatechange = getVerifyCode
//发送请求
xmlrequest.send();
}
}
function getVerifyCode()
{
//window.alert("0");
if(xmlrequest.readyState==4)
{
//window.alert("1");
//成功
if(xmlrequest.status==200)
{
var responseText=xmlrequest.responseText;
console.log(responseText);
//window.alert(responseText);
//$("#sp1").val(responseText);
//document.getElementById("sp1").innerHTML=responseText;
//document.getElementById("img1").src="/xiaoneinew/verifyCode";
$("[id='img1']").attr("src","/xiaoneinew/verifyCode2");
$("#sp3").html("${sesseionScope.verifyCode }");
console.log(1);
}
}
}
4.servlet产生验证码,并把图片输出到浏览器
package com.xiaonei.servlet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.taglibs.standard.tag.el.core.OutTag;
import com.mysql.cj.util.Base64Decoder;
@WebServlet("/verifyCode2")
public class VerifyCode2 extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public VerifyCode2() {
super();
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置响应类型
response.setContentType("image/JPEG");
//定义图片宽高
int width=80;
int height=50;
//创建一个缓冲区图片
BufferedImage img=new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
//使用缓冲区图片创建,图像对象用于绘制验证码
Graphics g=img.getGraphics();
//设置画笔颜色,后续画矩阵,相当于设置图形背景颜色为黄色
g.setColor(new Color(255,255,0));
//设置图片填充位置
g.fillRect(0, 0, width, height);
//设置字体样式
g.setFont(new Font("微软雅黑",Font.ITALIC,18));
String srand="";
Random random=new Random();
for(int i=0;i<4;i++)
{
int y=10+random.nextInt(40);
String rand=String.valueOf(random.nextInt(10));
srand+=rand;
System.out.println(rand);
//随机变换颜色
g.setColor(new Color(random.nextInt(255),random.nextInt(255),random.nextInt(255)));
//将随机数画入图形
g.drawString(rand, 5+i*width/4, y);
}
System.out.println("1:"+srand);
produceLine(g,random,width,height);
try
{
//释放图形资源
g.dispose();
//保存到session中
HttpSession session = request.getSession();
session.setAttribute("verifyCode",srand);
System.out.println("verifyCode:"+session.getAttribute("verifyCode"));
ServletOutputStream sos = response.getOutputStream();
ImageIO.write(img,"jpg",sos);
//禁止图像缓存。
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
//关闭输入流
sos.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
//随机生成30条线条
protected void produceLine(Graphics g,Random random,int width,int height)
{
int x=random.nextInt(width);
int y=random.nextInt(height);
int x1=random.nextInt(10);
int y1=random.nextInt(10);
g.drawLine(x, y, x1, y1);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
4.ajax回调函数接受servlet传递的字符串,并调用修改页面的验证码
function getVerifyCode()
{
//window.alert("0");
if(xmlrequest.readyState==4)
{
//window.alert("1");
//成功
if(xmlrequest.status==200)
{
var responseText=xmlrequest.responseText;
console.log(responseText);
//window.alert(responseText);
//$("#sp1").val(responseText);
//document.getElementById("sp1").innerHTML=responseText;
//document.getElementById("img1").src="/xiaoneinew/verifyCode";
$("[id='img1']").attr("src","/xiaoneinew/verifyCode2");
$("#sp3").html("${sesseionScope.verifyCode }");
console.log(1);
}
}
}
5.点击更换验证码,这样就产生了验证码,并且可以更换
6.那么如何验证验证码那,我的想法最初是servlet里不是更新了session吗,调用一个js函数把输入的内容与当前session里的验证码值作比较不就行了,试了很多遍都不行,因为ajax修改session的值需要刷新页面才能获取到最新的session,想了很多方法都不能实现
7.最后参考了一些网上的代码,明白了,可以通过ajax传递数据给一个servlet,把输入的验证码作为一个参数传递给servlet,在servlet里面可以获取session,然后servlet输入出一个验证成否的信息,从而完成了验证码的验证
调用的ajax
function check()
{
createXMLHttpRequest();
if(xmlrequest)
{
var verifyCode=$("#verifyCode").val();
var req="/xiaoneinew/checkVerifyCode?verifyCode="+verifyCode;
// window.alert(req);
xmlrequest.open("get",req,true);
//指定处理结果的函数
xmlrequest.onreadystatechange = getResult;
//发送请求
xmlrequest.send();
}
}
调用的servlet
package com.xiaonei.servlet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
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 org.apache.taglibs.standard.tag.el.core.OutTag;
@WebServlet("/checkVerifyCode")
public class CheckVerifyCode extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public CheckVerifyCode() {
super();
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter pw=response.getWriter();
String verifyCode=request.getParameter("verifyCode");
System.out.println("输入的验证码"+verifyCode);
String trueVerifyCode=(String) request.getSession().getAttribute("verifyCode");
System.out.println("真实的验证码:"+trueVerifyCode);
if(verifyCode.equals(trueVerifyCode))
{
pw.println(true);
}
else
{
pw.println(false);
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
ajax回调函数
function getResult()
{
//window.alert("0");
if(xmlrequest.readyState==4)
{
//window.alert("1");
//成功
if(xmlrequest.status==200)
{
var responseText=xmlrequest.responseText;
window.alert(responseText);
}
}
}