700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 利用ajax+jsp+servlet实现网页验证码的生成

利用ajax+jsp+servlet实现网页验证码的生成

时间:2022-06-18 17:57:24

相关推荐

利用ajax+jsp+servlet实现网页验证码的生成

效果如下。

点击9888的验证码,可以重新获取验证码。

实现方法主要是ajax+servlet+jsp

ajax部分(这段js需要在页面加载完后执行,不让可能找不到放图片的位置)

//向AjaxGet这个servlet发送post消息

function verification(){

http_request2.open("POST","../AjaxGet",true);

http_request2.setRequestHeader("Content-Type","application/x-www-form-urlencoded");

http_request2.onreadystatechange = callback;

http_request2.send("verificationR=true");

}

//回调函数,http_request2.onreadystatechange会监控页面的变化。当status为200(请求成功),readyState为4(处理完毕),将Verification-pic这个img的图片src属性设置为返回的base64图片。

function callback() {

var verificationImg = document.getElementById("Verification-pic");

if(http_request2.readyState==4&&http_request2.status==200){

verificationImg.src = "data:image/jpeg;base64,"+http_request2.responseText;

}

}

//点击验证码,发生刷新

function refulshVerfication(){

verification();

}

//定义http_request2,兼容不同属性的浏览器

var http_request2;

if(window.XMLHttpRequest){

http_request2 = new XMLHttpRequest();

}else if(window.ActiveXObject){

try{

http_request2 = new ActiveXObject("Msxml2.XMLHTTP");

}catch(e){

try{

http_request2 = new ActiveXObject("Microsoft.XMLHTTP");

}catch(e){}

}

}

verification();

servlet部分

package baseClass;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.io.PrintWriter;

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;

import org.apache.tomcat.util.codec.binary.Base64;

//主要负责处理ajax响应

public class AjaxGet extends HttpServlet {

public AjaxGet() {}

protected void processRequest(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

//设置一些响应头信息,禁止缓存

response.setContentType("image/jpeg");

response.setHeader("Prama", "no-cache");

response.setHeader("Coche-Control", "no-cache");

response.setDateHeader("Expires", 0);

PrintWriter output = response.getWriter();

//ServletOutputStream output = response.getOutputStream();

try {

//由于我这里该类负责响应注册页面和登录页面的验证码生成,所以会有两个。

String verificationL = request.getParameter("verificationL");

String verificationR = request.getParameter("verificationR");

System.out.println(verificationR);

System.out.println(verificationL);

if((verificationL!=null && verificationL.equals("true")) || (verificationR!=null && verificationR.equals("true"))) {

//Verification这个类负责生成验证码,

Verfication verificationImg = new Verfication();

//Verification.getString()返回字符串类型的验证码,createVerification返回的是BufferedImage的图像,将验证码的字符串放在session中,以便之后对用户输入进行比对。放在session中安全一点。前端不可直接读取。

HttpSession session = request.getSession(true);

if(verificationL!=null && verificationL.equals("true"))

session.setAttribute("vercodeL", verificationImg.getString());

else

session.setAttribute("vercodeR", verificationImg.getString());

ByteArrayOutputStream out = new ByteArrayOutputStream();

//需要对BufferedImage类型转化成字符串类型的base64格式,返回。在前端的ajax引擎可以监控到页面的返回变化,获得base64编码

ImageIO.write(verificationImg.createVerification(),"JPG",out);

String s = new String(Base64.encodeBase64(out.toByteArray()),"utf-8");

//转化未base64

System.out.println(s);

output.write(s);

}

else {

System.out.println("非验证");

}

} finally {

output.close();

}

}

//这个是HttpServlet的函数,这里进行重写,主要用于监控向该servlet类发送的post,get信息。

protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{

System.out.println("Get Infornation");

doPost(request, response);

}

protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{

System.out.println("Post Infornation");

processRequest(request, response);

}

}

servlet注册(写在web.xml文件中)

<servlet>

<servlet-name>AjaxGet</servlet-name>

<servlet-class>baseClass.AjaxGet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>AjaxGet</servlet-name>

<url-pattern>/AjaxGet</url-pattern>

</servlet-mapping>

Verification类(生成验证码)

package baseClass;

import java.awt.Color;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.image.BufferedImage;

import java.util.Random;

//产生验证码

public class Verfication {

public void Verification() {}

//保存验证码的字符串

private StringBuffer sbf = new StringBuffer();

protected BufferedImage createVerification() {

//图片的宽度和高度

int width = 100;

int height = 30;

//设置图片为RGB三色

BufferedImage verfication = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);

Graphics g = verfication.getGraphics();

Random random = new Random();

//设置背景色。我这里是偏向绿色的

g.setColor(new Color(random.nextInt(100),200,random.nextInt(100)));

//用上面的颜色填充整个图片

g.fillRect(0, 0, width, height);

//向图片中写入四个字符

for(int i=0;i<4;i++) {

g.setColor(Color.black);

g.setFont(new Font("华中隶书",Font.BOLD|Font.ITALIC,25));

int n = random.nextInt(10);

sbf.append(n);

//Graphics.drawString()这个函数的三个参数字符,坐标x,坐标y。这个坐标是字符左下角的坐标,不是一般的左上角

g.drawString(""+n, i*15+20, 22);

}

System.out.println(verfication);

//返回bufferedImage的验证码图片

return verfication;

}

public StringBuffer getString() {

return sbf;

}

}

jsp部分就不贴了,无非就是将用户输入的验证码和上面我们保存在session中的验证码比对一下。

基本上,一个动态的验证码就这样实现了。就是图片有点丑。后期需要再改进一下,并添加一些干扰点。防止爬虫直接通过ocr解析出验证码。

这里使用的主要是ajax和servlet的交互实现验证码的动态生成。 直接用ajax+jsp也可以实现的,就是丑了点。这样分成三块。

实现前后端分离。看着舒服点,下次servlet也可以复用。

制作过程中遇见了几个卡了很久的问题

主要是ajax和servlet的传输。刚开始时一直得不到数据,主要的问题是路径问题,以及对于servlet理解不足(一点理解也没有,直接开干,结果卡了好久2333)

1.Servlet类要在web.xml中注册才有效果

2.Servlet类(或者说所有在eclipse 的java web项目中的可调用类)都是指.class编译后的类。所以实际地址是.class类的地址。默认设置下在同个项目中引用地址只需要写 包名.类名 即可,如上面我的AjaxGet注册时,<servlet-class>中写的时baseClass.AjaxGet(前缀路径eclipse已经帮你考虑进去了)。

3.我一开始以为servlet是一个类,不可以直接访问的。我将servlet的web注册里的<url-pattern></url-pattern>写上了发送消息的页面的路径(我以为这个url-pattern是监控发送方来源的,现在想想有点蠢,如果是监控发送方来源的,那该页面的所有消息不都会被servlet截取了么,而且一个servlet只能处理一个网页的消息了。。。),ajax里的请求路径写的是jsp的路径。结果死活得不到消息。实际上url-pattern是监控请求目的地的,也就是接收方的。我这里的AjaxGet类就是接受方,url-pattern过滤匹配请求消息的地址,如果目的方路径是ajaxGet结尾的,ajaxGet类才会处理信息(url-pattern还有好几种匹配方式,详情见该博客/canger/p/6084846.html)。

4.js跳转到另一个页面,如果是相对地址,跳转地址应该是相对于引用该js的页面。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。