`
DxnPratice
  • 浏览: 18281 次
  • 性别: Icon_minigender_2
  • 来自: 长沙
社区版块
存档分类
最新评论

利用Ajax技术实现验证码的刷新和局部验证

阅读更多

<div class="iteye-blog-content-contain" style="font-size: 14px"></div>

先说点无关紧要的吧,两个知识点:

 (1),方法一:使用Js局部刷新验证码的做法是在页面中加上一个img标签,src属性设为一个servlet或者.jsp来请求验证码图片,html代码如下:

<img src="ImageServlet" onclick="refresh(this)"/>

 在一般情况下刷新一次页面,验证码图片也会变化一次,但有时候我们希望验证码图片变化时不刷新整个页面,也就是局部刷新的效果,代码如下:

js代码:

<

script type="text/javascript">
function refresh(obj){
obj.src="ImageServlet?id="+Math.random();
}
</script>
 其中需要注意的是请求路径中必须要有参数(参数名可随意定义),参数值不能是一个固定值而是随机数。代码中obj对象是指img标签对象。
方法二:
html代码如下:
<img src="ImageServlet"  id="picture" ><span style='color:#0000cc'  onclick="refresh()">看不清,换一张</span>
 js代码如下:
function refresh(){
	 document.getElementById("picture").src="ImageServlet?id="+Math.random();
}
 (2),获取图片的ImageServlet代码如下:
package servlet;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
 * Servlet implementation class ImageServlet
 */
public class ImageServlet extends HttpServlet {
// 定义可选择的字符
private static final String CHARS = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ";
static Random random = new Random();
 // 得到一个随机的字符串
private String getRandomString() {
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < 4; i++) { // 生成四个字符
buffer.append(CHARS.charAt(random.nextInt(CHARS.length())));}
return buffer.toString();
}
// 随机背景颜色
public static Color getRandomColor() { // 得到随机颜色
return new Color(random.nextInt(128) + 127, random.nextInt(128) + 127,random.nextInt(128) + 127);
    }
    public static Color getReverseColor(Color c) { // 得到颜色的反色
	return new Color(255 - c.getRed(), 255 - c.getGreen(),
					255 - c.getBlue());
		}
  public void doGet(HttpServletRequest request, HttpServletResponse response)
				throws ServletException, IOException {
		response.setContentType("image/jpeg"); // 设置输出类型
     // 得到随机字符串
	String randomString = getRandomString();
			// 将getSession()设置为true,当会话不存在是返回null
			request.getSession(true).setAttribute("randomString", randomString);
			// 设置图片的宽、高
			int width = 80;
			int height = 30;

			Color bcolor = getRandomColor(); // 设置背景色
			Color fcolor = getReverseColor(bcolor); // 前景色

			// 创建一个彩色图片
			BufferedImage bimage = new BufferedImage(width, height,
					BufferedImage.TYPE_INT_BGR);
			// 创建绘图对象,从bimage上得到的绘制对象,会把数据绘制到bimage上
			Graphics2D g = bimage.createGraphics();
			// 字体样式为宋体,加粗,20磅
			g.setFont(new Font("Vijaya", Font.BOLD, 20));
			// 先画出背景色
			g.setColor(bcolor);
			g.fillRect(0, 0, width, height);

			// 再画出前景色
			g.setColor(fcolor);
			for (int i = 0; i < randomString.length(); i++) {
				// 绘制随机字符
				g.drawString(randomString.charAt(i) + "", 10 + i * 12, 22);
			}

			// 画出干扰点
			for (int i = 0, n = random.nextInt(100); i < n; i++) {
				g.fillRect(random.nextInt(width), random.nextInt(height), 1, 1);
			}

			// 将图像输出到浏览器
			ServletOutputStream outstream = response.getOutputStream();
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(outstream);

			encoder.encode(bimage);
			outstream.flush();

			outstream.close();
		}
	}

 现在说到核心的Ajax技术:

传统web页面的服务是基于http协议的,所以它永远也改变不了“请求响应”的模式。你必须“点”一下,它才能动一下,而且每次都必须刷新整个页面,这也意味着服务器要将所有页面上的数据传送下来,即使你的点击只是需要改变页面上一行十个字的内容; AJAX代码运行在浏览器和服务器之间,通过编程,你可以让ajax代码仅从服务器上提取需要改变的数据,也只改变页面中需要改变的某一部分:某一个div层、表格中的某一个单元格。用户不会看到页面全部被刷新了;当使用了ajax技术时,用户发送请求时(点击事件)将交由ajax代码处理,用户请求即完成。AJAX代码随后自己将请求发送给服务器,一旦服务器返回的响应,AJAX代码即根据返回的业务更新页面上的某个部分,这部分是由AJAX处理完成,与用户操作流程无关。

 

我们以一个典型的示例:即时验证是否有重复用户名的AJAX应用为例,讲解AJAX编写的基本步骤

1,当用户输入用户名后,焦点离开输入框,即触发输入框的onBlur事件,这个事件将调用js编写的ajax代码,将用户输入发送给服务器验证,并将服务器返回的结果消息显示在输入框下面的div层上。

这个流程将由三部分组成:

login.html:用户填写用户名的页面:

CheckUserNameServlet.java:服务器上用来验证用户名的Servlet,返回一个字符串作为结果;

Js编写的AJAX代码:请送请求,并更新页面

AJAX第一步:创建XMLHTTPRequest对象;

  XMLHTTPRequest是AJAX应用中的核心API,它被js调用以向服务器发送请求,并异步接收服务器返回的数据后,更新局部页面。使用AJAX功能时,首先要在js中创建XMLHTTPRequest对象: 

<script type="text/javascript">
//定义了XMLHttpRequest对象
 var request; 
   //创建XMLHttpRequest对象函数
     function getRequestObject() { 
       if (window.ActiveXObject) { 
          request=new ActiveXObject("Microsoft.XMLHTTP"); 
        } else if (window.XMLHttpRequest) { 
          request=new XMLHttpRequest(); 
        } else { 
          window.alert("你的浏览器不支持XMLHTTPRequest,将无使用AJAX功能!");
        } 
     } 
  </script>

 在这段脚本中,getRequestObject函数调用后,将创建一个XMLHTTPRequest对象。注意其中的if判断,因为这世界还不是平的,IE和FireFox是有差别的;第一个if判断如果是IE浏览器,则调用MS的请求对象,第二个在浏览器是FireFox、Netscape的情况下会有效;当然,最后实在不行了,就告诉用户这玩不成啦。

AJAX第二步:编写回调方法;

  现在我们有了请求对象,接下来要考虑的是XMLHTTPRequest对象向服务器发送请求后,服务器返回的结果应该如何处理,即AJax中的回调方法;在实现这个处理逻辑前先看一下页面的html代码:

<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>AJAX检测重复用户名 蓝杰信息@NetJava.cn</title>
</head>
<body>
 
<br>注册用户名:<input type="text" name="userName"/>
<!-- 这个div层内将显示ajax从服务器返回的消息 -->
<div id=divErrorName" style="color:red;"></div>
<br>注册  密码:<input type="password" name="userPWD"/>
<br><input type="button" name="regUser" value="注册"/>
</body>
</html>

 回调方法要实现的逻辑很简单,就是将CheckUserNameServlet.java这个Servlet返回的消息显示到名字为divErrorName的div中。如下代码:

//回调方法实现:将服务器返回的消息更新到div中
function processResult() { 
       if ((request.readyState == 4) && 
             (request.status == 200)) { 
          //1.弹出对话框以便调试
         alert("服务器返回的是: "+request.responseText); 
         //显示到指定的组件中
       document.getElementById("divErrorName").innerHTML=request.responseText;
        } 
     }

 上面这段代码,关键在if判断语句,请求对象的readyState属性值代表请求对象的当前状态,为4时,代表己处理完成;而status为http应答代码,200表示服务器响应OK,如果是404呢?

   如果请求对象己处理完毕,服务器返回的应答码也是OK的了,就请求对象的responseText属性值就代表了服务器返回给客户端的文本内容。

AJAX第三步:发送异步请求

必须清楚的知道,AJAX发送的请求也是通过HTTP协议传送着,这意味着ajax也可以发送get或post请求,请看如下代码:

function sendRequest() { 
          //创建XMLHTTPRequest对象
          getRequestObject();
          //绑定回调方法,
          request.onreadystatechange=processResult; 
          //发送请求
         // request.open("GET", "index.jsp", true); 
         //发送Post请求
          request.open("POST", "servlet/CheckUserNameServlet", true);
          request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
          var userName=document.getElementById("userName").value;
          //将userName做为请求参数发送上去
          request.send("userName="+userName); 
        }

 CheckUserNameServlet代码如下:

public class CheckUserNameServlet extends HttpServlet {	
private static final long serialVersionUID = 1L;
     protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
        String userName = request.getParameter("userName");
		System.out.println("收到了请求"+username);
		PrintWriter out = response.getWriter();
		if(userName.equals("newer")){
			out.write("用户名已经被占用");
		}else{
			out.write("该用户名可以被使用");
		}
		out.flush();
	}

}

 完整的html页面完整代码如下:

 

<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>AJAX检测重复用户名 蓝杰信息@NetJava.cn</title>
</head>
<body>
 <script type="text/javascript">
  //定义了XMLHttpRequest对象
 var request; 
   //创建XMLHttpRequest对象函数
     function getRequestObject() { 
       if (window.ActiveXObject) { 
          request=new ActiveXObject("Microsoft.XMLHTTP"); 
        } else if (window.XMLHttpRequest) { 
          request=new XMLHttpRequest(); 
        } else { 
          window.alert("你的浏览器不支持XMLHTTPRequest,将无使用AJAX功能!");
        } 
     } 
     
      //回调方法实现:将服务器返回的消息更新到div中
function processResult() { 
       if ((request.readyState == 4) && 
             (request.status == 200)) { 
          //1.弹出对话框以便调试
         alert("服务器返回的是: "+request.responseText); 
         //显示到指定的组件中
document.getElementById("divErrorName").innerHTML=request.responseText;
        } 
     }
     
     //发送请求,绑定回调方法 
 function sendRequest() { 
          //创建XMLHTTPRequest对象
          getRequestObject();
          //绑定回调方法,
          request.onreadystatechange=processResult; 
          //发送请求
         // request.open("GET", "index.jsp", true); 
         //发送Post请求
          request.open("POST", "servlet/CheckUserNameServlet", true);
          request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
          var userName=document.getElementById("userName").value;
          //将userName做为请求参数发送上去
          request.send("userName="+userName); 
        }   
  </script>
<br>注册用户名:<input type="text" name="userName" onBlur="sendRequest();"/>
<!-- 这个div层内将显示ajax从服务器返回的消息 -->
<div id="divErrorName" style="color:red;"></div>
<br>注册  密码:<input type="password" name="userPWD"/>
<br><input type="button" name="regUser" value="注册"/>
</body>
</html>

 4,通过上面的Ajax三部曲,现在回到验证码刷新和验证

1,页面实现:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">

function refresh(){
	 document.getElementById("picture").src="ImageServlet?id="+Math.random();
}

var request;//异步请求对象
function createXMLHttpRequest() {
	if (window.ActiveXObject) {
		request = new ActiveXObject("Microsoft.XMLHTTP");
	} else if (window.XMLHttpRequest) {
		request = new XMLHttpRequest();
	} else {
		window.alert("你的浏览器不支持XMLHTTPRequest,将无使用AJAX功能!");
	}
}

//回调函数[响应之后执行的函数]
function processResult() {
	if ((request.readyState == 4) && (request.status == 200)) {
		var str = request.responseText;
		
		if(str=="true"){
			//显示到指定的组件中
			alert("恭喜你!!!验证码正确");
		}else{
			//显示到指定的组件中
			alert("验证码错误!!!!");
		}
		
	}
}

//发送请求,绑定回调方法 
function sendRequest() {
	//创建XMLHTTPRequest对象
	createXMLHttpRequest();
	//绑定回调方法,
	request.onreadystatechange = processResult;
	//获得输入框中的内容
	var validate = document.getElementById("Validate").value;
	
	//发送请求
	// request.open("GET", "AccountCheckServlet?username="+username, true); 
	//发送Post请求
	request.open("POST", "validateServlet", true);
	request.setRequestHeader("Content-Type",
			"application/x-www-form-urlencoded");
	//将userName做为请求参数发送上去
	request.send("validate=" + validate);
	//request.send(null);
}
</script>
<body>
用户名:<input type="text" name="userName"><br/>
验证码:<input type="text" name="Validate" value="Validate" onblur="sendRequest()">< img src="ImageServlet" id="picture"><span style='color:#0000cc'  onclick="refresh()">看不清,换一张</span>

 

 2,ImageServlet获取图片,代码见本文档开始处;

package servlet;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
 * Servlet implementation class ImageServlet
 */
public class ImageServlet extends HttpServlet {
	// 定义可选择的字符
		private static final String CHARS = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ";
		static Random random = new Random();

		// 得到一个随机的字符串
		private String getRandomString() {
			StringBuffer buffer = new StringBuffer();
			for (int i = 0; i < 4; i++) { // 生成六个字符
				buffer.append(CHARS.charAt(random.nextInt(CHARS.length())));
			}
			return buffer.toString();
		}

		// 随机背景颜色
		public static Color getRandomColor() { // 得到随机颜色
			return new Color(random.nextInt(128) + 127, random.nextInt(128) + 127,
					random.nextInt(128) + 127);
		}

		public static Color getReverseColor(Color c) { // 得到颜色的反色
			return new Color(255 - c.getRed(), 255 - c.getGreen(),
					255 - c.getBlue());
		}

		public void doGet(HttpServletRequest request, HttpServletResponse response)
				throws ServletException, IOException {
			response.setContentType("image/jpeg"); // 设置输出类型

			// 得到随机字符串
			String randomString = getRandomString();
			// 将getSession()设置为true,当会话不存在是返回null
			request.getSession(true).setAttribute("randomString", randomString);
			// 设置图片的宽、高
			int width = 80;
			int height = 30;

			Color bcolor = getRandomColor(); // 设置背景色
			Color fcolor = getReverseColor(bcolor); // 前景色

			// 创建一个彩色图片
			BufferedImage bimage = new BufferedImage(width, height,
					BufferedImage.TYPE_INT_BGR);
			// 创建绘图对象,从bimage上得到的绘制对象,会把数据绘制到bimage上
			Graphics2D g = bimage.createGraphics();
			// 字体样式为宋体,加粗,20磅
			g.setFont(new Font("Vijaya", Font.BOLD, 20));
			// 先画出背景色
			g.setColor(bcolor);
			g.fillRect(0, 0, width, height);

			// 再画出前景色
			g.setColor(fcolor);
			for (int i = 0; i < randomString.length(); i++) {
				// 绘制随机字符
				g.drawString(randomString.charAt(i) + "", 10 + i * 12, 22);
			}

			// 画出干扰点
			for (int i = 0, n = random.nextInt(100); i < n; i++) {
				g.fillRect(random.nextInt(width), random.nextInt(height), 1, 1);
			}

			// 将图像输出到浏览器
			ServletOutputStream outstream = response.getOutputStream();
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(outstream);

			encoder.encode(bimage);
			outstream.flush();

			outstream.close();
		}
	}

 

3,服务器对于Ajax请求是如何处理的呢?即validateServlet

package servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class validateServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String validate= request.getParameter("validate");
		String randomString=(String)request.getSession(true).getAttribute("randomString");
		PrintWriter out=response.getWriter();
		if(validate.equalsIgnoreCase(randomString)){
		 out.write("true");
	 }else{
		 out.write("false");
	 }
	
	}

}

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics