使用Servlet制作网页验证码

验证码简介

      对于验证码,相信每个人都不会陌生,当我们在一个网站进行注册登录时,发布帖子时,经
   常需要输入验证码进行验证,但其实这对用户体验来说很不友好,我们需要多输入一次和我们貌
   似没有太大关系的数据,那为什么大多数网站都有网页验证码呢?

这是没有验证码登录


那么没有验证码会带来哪些问题?
 1. 对特定用户不断登录破解密码
 2. 对某个网站重复创建账户
 3. 对某个网站提交垃圾数据
 4. 对某网站刷票
 所以使用验证码还是很有必要的!

用Servlet实现验证码步骤


首先是制作页面

验证码包含两个部分:输入框和图片

输入框很简单<input type="text" name="verifyCode" />

图片不太一样<img alt="验证码" id="checkcode" src="<%=request.getContextPath() %>/ImageServlet" 这里src并不是指向一个固定的图片,而是指向我们用于生成图片的ImageServlet类,request.getContextPath()得到当前项目路径。

生成图片
  • 生成图片所需要的类
    1.BufferedImage类(存放图片)
    2.Graphics类(绘制图片,字体)
    3.Color类(设置颜色)
    4.Random(生成图片上的随机字符)
    5.ImageIO类(输出图片)

  • 生成图片的实现类
    1.定义BufferedImage对象
    2.获得Graphics对象
    3.获得Random产生随机验证码信息
    4.使用Graphics绘制图片
    5.记录验证码到session中
    6.使用ImageIO输出图片

  • 校验验证码是否正确
    1.获取页面验证码
    2.获取session中保存的验证码
    3.比较验证码
    4.返回校验结果

实现流程

实现流程


代码实现

  • 生成验证码

    首先是图片生成类ImageServlet

    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    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;
    
    @WebServlet("/ImageServlet")
    public class ImageServlet extends HttpServlet{
      @Override
    
      //生成图片并设置颜色大小
        BufferedImage bi = new BufferedImage(68, 22, BufferedImage.TYPE_INT_RGB);
        Graphics g = bi.getGraphics();
        Color c = new Color(200, 150, 255);
        g.setColor(c);
        g.fillRect(0, 0, 68, 22);
    
     //生成一个字符数组,从中随机抽取字符
        String str = "ABCDEFGHI0123456789";
        char[] ch = str.toCharArray();
        Random r = new Random();
        int len = ch.length,index;
    
    //随机抽取4位字符画入图片并将字符存入StringBuffer中
        StringBuffer sb = new StringBuffer();
        for(int i =0 ;i<4;i++) {
            index = r.nextInt(len);
            g.setColor(new Color(r.nextInt(88), r.nextInt(188), r.nextInt(255)));
            g.drawString(ch[index]+"", (i*15)+3, 18);
            sb.append(ch[index]);
        }
    
    //将StringBuffer中的字符存入Session中以备后续校验,并输出图片
        request.getSession().setAttribute("piccode", sb.toString());
        ImageIO.write(bi, "JPG", response.getOutputStream());
      }
    }
    

此时运行服务可以看到页面显示出验证码
验证码图片
通常验证码后面有“看不清楚”,然而此时点击并没有反应,因为我们并没有设置这个标签的链接,这里就用到javascript,设置<a href="javascript:reloadCode();">看不清楚</a>a标签指向一个javascript的reloadCode()函数,点击链接就会刷新出不同的图片,所以我们只是重新加载一次 ImageServlet类 生成图片,代码如下:

   <script type="text/javascript">
   function reloadCode(){
       var time = new Date().getTime();
       //获取元素名为imagecode的元素并设置其src路径指向ImageServlet类
       document.getElementById("imagecode").src="<%=request.getContextPath() %>/ImageServlet?d="+time;
   }
</script>

这里为什么要加一个time变量呢?这是因为我们如果不加time变量那么图片的路径是没有变化的,浏览器觉得加载同一张图没有必要,不知道是新的请求还是旧的请求,所以图片并不会变化,而加入time之后每次加载的都不是同一张图片,从而进行刷新图片。

  • 校验验证码

    用户输入图片内容之后接下来就是校验验证码是否正确,我们将页面上的表单提交给LoginServlet类进行处理,处理的流程就是:

    1.将Session中存的内容取出来
    2.将用户输入的内容提取出来
    3.进行比较,并输出比较结果
    

LoginServlet类

public class LoginServlet extends HttpServlet{
   @Override
   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      response.setCharacterEncoding("GBK");

      //取出两者内容传给piccode,checkcode。
      String piccode = (String) request.getSession().getAttribute("piccode");
      String checkcode = request.getParameter("checkcode");

      //将用户输入的字符转换成大写
      checkcode = checkcode.toUpperCase();
      PrintWriter out = response.getWriter();

      //进行比较并返回结果
      if(checkcode.equals(piccode)) {
          out.println("验证码输入正确!");
      }else {
          out.println("验证码输入错误!");
      }
      out.flush();
      out.close();
  }
}

到这里我们的验证码就完成了,赶紧打开页面去试试吧!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值