【JSP生成验证码】

验证码的出现有效地防止了服务器被恶意利用的问题的出现。So,现在的应用基本都会用到验证码,而对于我们来说,需要掌握的不仅仅是验证码的作用,所以今天就做了一个简单的验证码。虽然目前市面上有很多第三方验证码接口或者框架,例如ValidateCode.jar等,还是自己动手做一个玩玩。(哈哈哈,废话一啪啦)。

为了玩这个,还回去看了一下j2se的内容(java画图就没怎么玩...)

先准备一个生成验证码图的jsp,CheckCodeImg.jsp,步骤就在注释中,基本是j2se的知识,就不赘述了。

不过还是说说代码第一行吧,contentType需要写为:image/jpeg。表示整个文件类型为jpeg图片。

最后一行代码:开始时:out=pageContext.getOut()得到的是jsp内置out对象,后来pushBody得到的是一个新的ContextBody对象,他们是二个对象
ContextBody是JspWriter的子类;即:jsp内置out对象是父,pushbody得到的是子,
所以这里的out.close()其实不是close掉jsp的内置out对象,而是ContextBody的实例对象;

在jsp执行完后会释放所有内置对象,这里我们将该对象释放!

基本执行的顺序是:

1.生成验证码,并将验证码真实值放入session域中

2.显示验证码,将用户输入验证码值传回后端等待比对结果

3.后端接前端用户输入验证码值并和session中真实的验证码值比对,返回处理结果

4.前端接受返回结果,根据返回的值来显示给用户。

<%@ page contentType="image/jpeg;charset=UTF-8" language="java" %>
<%@ page import="java.awt.*" %>
<%@ page import="java.util.Random" %>
<%@ page import="java.awt.image.BufferedImage" %>
<%@ page import="javax.imageio.ImageIO" %>
<%! 
	//生成随机颜色
	 public Color getColor()
	 {
		Random ran=new Random();
		int R=ran.nextInt(255);
		int G=ran.nextInt(255);
		int B=ran.nextInt(255);
		return new Color(R,G,B);
	 }
	//生成随4位机数字验证码
	public String codeGenerate()
	{
		int code=(int)(Math.random()*9000+1000);
		return String.valueOf(code);
	}
%>

<%
	//禁止缓存,防止验证码过期
	response.setHeader("Pragma","no-cache");
	response.setHeader("Cache-Control","no-cache");
	response.setHeader("Expires","0");
	//实例化一个image长度和宽度分别是80 30
	BufferedImage image=new BufferedImage(80,30,BufferedImage.TYPE_INT_RGB);
	//取画笔,准备画图
	Graphics pen=image.getGraphics();
	//填充该矩形image
	pen.fillRect(0, 0, 80, 30);
	//设置文字样式
	pen.setFont(new Font("seif",Font.BOLD,20));
	//设置画笔颜色
	pen.setColor(Color.BLACK);
	//获取随机数验证码值
    String checkCode = codeGenerate() ;
	//处理该验证码值的每一位数字
    StringBuffer sb = new StringBuffer() ;
     for(int i=0;i<checkCode.length();i++){
         sb.append(checkCode.charAt(i)+" "  )  ;
     }
    //绘制验证码
     pen.drawString( sb.toString(), 15,20 );
    //绘制干扰线条
     for(int i=0;i<20;i++)
    {
        Random ran = new Random() ;
        //产生随机起始位置
        int xBegin = ran.nextInt(80) ;//55
        int yBegin = ran.nextInt(30) ;
		//干扰线条末端位置
        int xEnd = ran.nextInt(xBegin +15 ) ;
        int yEnd = ran.nextInt(yBegin + 15) ;
		//设置随机线条颜色
        pen.setColor( getColor());
        pen.drawLine(xBegin,yBegin,xEnd,yEnd);
    }
    //将验证码真实值 保存在session中,供使用时比较真实性
    session.setAttribute("CKECKCODE"  ,checkCode );
    //真实的产生图片
    ImageIO.write(image,"jpeg",  response.getOutputStream()) ;
    //关闭
    out.clear();
    out = pageContext.pushBody() ;
%>

然后,再写另一个jsp,来测试这个验证码,就叫test.jsp 

这里用了jq,在我的服务器端有一个文件夹imgs里面放了两个图片,分别是 x 和 ✔,当输入框失去焦点,会自动使用ajax方式请求后台并判断验证码是否正确,若正确就显示✔,否则显示 x。此外点击验证码可以刷新一张新的验证码。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <script type="text/javascript" src="jquery-3.3.1.js" >
    </script>
    <script type="text/javascript" >
	//实现点击一下验证码就刷新一张
      function reloadCheckImg()
      {
          $("img").attr("src", "CheckCodeImg.jsp?"+(new Date().getTime()));  //<img src="...">
      }

      $(document).ready(function()
   {

        $("#checkcodeId").blur(function()
       {

          var $checkcode = $("#checkcodeId").val();
          //校验   :文本框中输入的值 发送到服务端。
           //服务端: 获取文本框输入的值 ,和真实验证码图片中的值对比 ,并返回验证结果
          $.post(
                  "ServiceCheckCode",//服务端地址
                  "checkcode="+$checkcode ,
                  function(result)
                  {
                 	 var resultHtml =  $("<img src='"+result+"' height='15' width='15px'   />") ;
                    $("#tip").html(resultHtml);
                  }
          		);
        });
      });
    </script>
    
    <title>验证码</title>
  </head>
  <body>
        验证码:
          <input type="text" name="checkcode" id="checkcodeId" size="4"  />
          <!-- 验证码-->
       	 <a href="javascript:reloadCheckImg();"> <img src="CheckCodeImg.jsp"/></a>
       	<span id="tip">  </span>
  </body>
</html>

。最后,服务端代码,ServiceCheckCode.java;简单地从session中拿到验证码的值,然后和前端test.jsp传来的验证码值进行比对,若比对成功,将提示正确的图片地址返回去,让前端显示(就是那个 ✔)。否则默认返回表示错误的图片地址。

package com.charles.service;

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

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet("/ServiceCheckCode")
public class ServiceCheckCode extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	      String resultTip = "imgs/wrong.jpg";
	        //获取用户输入验证码
	       String checkcodeClient =  request.getParameter("checkcode");

	       //真实的验证码值
	       String checkcodeServer = (String) request.getSession().getAttribute("CKECKCODE");
	       if(checkcodeServer.equals(checkcodeClient)){
	           resultTip = "imgs/right.jpg";
	       }
	       response.setContentType("text/html;charset=UTF-8");
	        PrintWriter writer = response.getWriter();//输出流
	        writer.write(resultTip);
	        writer.flush();
	        writer.close();
	}

}

 最后附上两张测试图

                                    正确                                                                                                                       错误

原创文章 42 获赞 72 访问量 8214

猜你喜欢

转载自blog.csdn.net/weixin_43249548/article/details/101381332
今日推荐