案例需求:编写用户登陆页面的验证码模块,在用户进行登陆时,输入验证码后不需要点击提交按钮,使用AJAX异步地向服务器发送验证验证码的请求。如果验证码正确,可以点击提交按钮,如果验证码输入错误,提示用户。如果用户看不清验证码,点击验证码还可以刷新出新的验证码。
案例实现:
验证码原理:当页面请求一个验证码的Servlet时,这个Servlet会把数据以图片的形式传给客户端,并把数据以字符串的形式存入了session中。当用户以图片为标准输入对应的验证码并发送给对应的用来验证验证码的Servlet时,验证验证码的Servlet收到用户输入的数据,并从session取出对应的验证码字符进行验证即可。
● 定义向客户端发送验证码的Servlet。详细代码如下:
package com.xdl.servlet;import com.sun.image.codec.jpeg.JPEGCodec;import com.sun.image.codec.jpeg.JPEGImageEncoder;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 javax.servlet.http.HttpSession;import java.awt.*;import java.awt.image.BufferedImage;import java.io.IOException;import java.io.OutputStream;import java.util.Random;@WebServlet("/checkCode")public class CheckCode extends HttpServlet { public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("image/jpeg"); BufferedImage image = new BufferedImage (60, 20, BufferedImage. TYPE_INT_RGB); Graphics g = image.getGraphics(); Random r = new Random(); g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255))); g.fillRect(0, 0, 60, 20); g.setColor(new Color(0,0,0)); String number = String.valueOf(r.nextInt(99999)); HttpSession session = request.getSession(); session.setAttribute("number", number); g.drawString(number, 5, 15); g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255))); g.drawLine(r.nextInt(60), r.nextInt(20), r.nextInt(60), r.nextInt(20)); OutputStream os = response.getOutputStream(); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os); encoder.encode(image); }}
● 定义用来验证验证码准确性的Servlet。详细代码如下:
package com.xdl.servlet;import java.io.IOException;import java.io.PrintWriter;import java.util.HashMap;import java.util.Map;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 net.sf.json.JSONObject;@WebServlet("/validateCheckCode")public class ValidateCheckCode extends HttpServlet { protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); String code = request.getParameter("code"); String answer = (String)request.getSession().getAttribute("number"); Mapinfo = new HashMap<>(); if(code.equals(answer)){ info.put("state", 1); info.put("msg", "验证码正确"); }else{ info.put("state", 0); info.put("msg", "验证码不正确"); } String jsonStr = JSONObject.fromObject(info).toString(); PrintWriter pw = response.getWriter(); pw.write(jsonStr); pw.close(); }}
● 编写客户端页面,包括用户名输入框、密码输入框、以及验证码输入框和提交按钮。详细代码如下:
Title
目前全部的代码已经编写完成,我们打开Tomcat服务器,在浏览器中输入http://localhost:8080/checkcode/login.html。浏览器将出现如图2所示的页面。
此时是无法点击登陆按钮的,因为我们的验证码没有通过验证,现在我们输入正确的验证码,然后将鼠标移出验证码输入框。
图2 login.html
图3 输入了正确的验证码
我们输入了正确的验证码,并且服务器也已经验证通过了,现在我们就可以点击登陆按钮了。
现在我们输入错误的验证码来看看页面上会出现什么效果。
可以看到我们输入了错误的验证码,服务器检查没有通过,登陆按钮还是不可点击的。
有时我们页面上面的验证码不清晰,不能很好的辨认其中的字符,所以在我们的登陆页面中,为验证码图片添加了一个单击事件,当点击验证码图片时,页面会使用Ajax重新向服务器发送新的请求来刷新验证码。
图4 输入错误的验证码后,提示验证码
图5 使用AJAX向服务端重新获取验证码
不正确,并且登陆按钮无法点击