专栏首页Python程序员杂谈Servlet生成数字验证码及判断

Servlet生成数字验证码及判断

为了提高网站的安全性,或者软件的安全性,现在再输入用户名和密码进行网站或者软件登陆的时候,如果输错一次就会出现输入验证码这一项,主要是为了保护账号不被暴力破解。这里我简单实现一下验证码。 使用Servlet生成验证码部分是摘自javaeye,有现成的代码直接使用就好了。不过前台这块纠结了半天,本来是打算用js对输入的验证码进行判断结果发现实现不了。最后只能写jsp脚本实现了。 首先是Servlet代码:SimpleCaptchaServlet.java:

package com.web;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.*;

/**
 * 生成验证码的Servlet
 * @author 胡阳
 * 注:该代码参考自javaeye
 *
 */
public class SimpleCaptchaServlet extends HttpServlet {

    public void doGet(HttpServletRequest req,HttpServletResponse res) throws ServletException, IOException
    {
            res.setContentType("image/jpeg");
            res.setHeader("Pragma","No-cache");
            res.setHeader("Cache-Control","no-cache");
            res.setDateHeader("Expires", 0);
            HttpSession session = req.getSession(true);

            // 在内存中创建图象
            int width=60, height=20;
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

            // 获取图形上下文
            Graphics g = image.getGraphics();

            // 生成随机类
            Random random = new Random();

            // 设定背景色
            g.setColor(getRandColor(200,250));
            g.fillRect(0, 0, width, height);

            // 设定字体
            g.setFont(new Font("Times New Roman",Font.PLAIN,18));

            // 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
            g.setColor(getRandColor(160,200));
            for (int i=0;i<155;i++)
            {
                    int x = random.nextInt(width);
                    int y = random.nextInt(height);
                    int xl = random.nextInt(12);
                    int yl = random.nextInt(12);
                    g.drawLine(x,y,x+xl,y+yl);
            }

            // 取随机产生的认证码(4位数字)
            String sRand="";
            for (int i=0;i<4;i++)
            {
                String rand=String.valueOf(random.nextInt(10));
                sRand+=rand;
                // 将认证码显示到图象中
                g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
                    // 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
                g.drawString(rand,13*i+6,16);
            }

            // 将认证码存入SESSION
            session.setAttribute("VerifyCode",sRand);

            // 图象生效
            g.dispose();

            // 输出图象到页面
            ImageIO.write(image, "JPEG", res.getOutputStream());
            //JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(res.getOutputStream());
            //encoder.encode(image);
    }

    public void doPost(HttpServletRequest req,HttpServletResponse res) throws ServletException, IOException
    {
            doGet(req,res);
    }

    //给定范围获得随机颜色
    private Color getRandColor(int fc,int bc)
    {
            Random random = new Random();
            if(fc>255) fc=255;
            if(bc>255) bc=255;
            int r=fc+random.nextInt(bc-fc);
            int g=fc+random.nextInt(bc-fc);
            int b=fc+random.nextInt(bc-fc);
            return new Color(r,g,b);
    }
}

然后配置xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:javaee="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <servlet>
        <servlet-name>SimpleCaptchaServlet</servlet-name>
        <servlet-class>com.web.SimpleCaptchaServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>SimpleCaptchaServlet</servlet-name>
        <url-pattern>/servlet/SimpleCaptchaServlet</url-pattern>
    </servlet-mapping>
</web-app>

最后index.jsp页面:

<%@ page language="java" contentType="text/html; charset=GB18030"
    pageEncoding="GB18030"%>
<%
    String verifyCode = (String)session.getAttribute("VerifyCode");
    String command = request.getParameter("command");
    String anthCode = request.getParameter("authCode");

    if ("ok".equalsIgnoreCase(command)) {
        if (anthCode != null && anthCode.equalsIgnoreCase(verifyCode)) {
            out.print("测试成功!");
        } else{
            out.println("验证码错误!");
        }

    }

%>
<!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=GB18030">
<title>Insert title here</title>
<script language=JavaScript>
    function change(field) {
        /*采用ajax的话可以使用这个代码,另外还需要从服务器端得到当前验证码
        var timenow = new Date().getTime();
        field.src="servlet/SimpleCaptchaServlet?d=" + timenow;
        */
        document.URL=location.href;
    }

</script>
</head>
<body>
    <form action="index.jsp">
        <input type="hidden" name="command" value="ok">
        <input id="authCode" name="authCode" type="text" size="6" maxlength="4">
        <img src="servlet/SimpleCaptchaServlet" alt="验证码" onClick="change(this);">
        <input name="ok" type="submit" value="确定">
    </form>
</body>
</html>

比较简单。

—EOF—

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • pypy2.0.2成功运行Django1.5+Mysql

    接上篇文章说, 上篇文章 最后提到,在Django创建针对mysql的connection时,传递了两个参数: charset 和 use_unicode 导致...

    the5fire
  • 详解数据库自然连接

    自然连接:是一种特殊的等值连接,它要求两个关系进行比较的分量必须是相同的属性组,并且在结果集中将重复属性列去掉。

    the5fire
  • 编译Python3.7并配置ssl库为LibreSSL

    下载源码,手动编译:./configure --prefix=/opt/python/,安装: make && make install。

    the5fire
  • 【12.2新特性】在Oracle Active Data Guard上部署列式存储

    摘要:本文将介绍Oracle 12.2中关于ADG的新特性,在ADG上部署列式存储。关于12.2更多新特性, 注:本文来自官方文档翻译。 一、In-Memory...

    数据和云
  • 【leetcode刷题】T179-最小差值 II

    https://leetcode-cn.com/problems/smallest-range-ii

    木又AI帮
  • 掌握MySQL数据库这些优化技巧,事半功倍!

    一个成熟的数据库架构并不是一开始设计就具备高可用、高伸缩等特性的,它是随着用户量的增加,基础架构才逐渐完善。这篇文章主要谈谈MySQL数据库在发展周期中所面临的...

    lyb-geek
  • 基于深度学习的通用物体检测算法对比探索【附PPT与视频资料】

    目前基于深度学习的通用物体检测算法大致可以分为两类:一步法检测器和二步法检测器。一步法检测器有较高的检测速度,但检测精度不如二步法检测器。而二步法检测有较高的检...

    马上科普尚尚
  • LeetCode 316. Remove Duplicate Letters(贪心)

    题解:贪心,咱们从结果字符串的左边开始,左边第一个字符在原字符串中的右边一定有n-1个不同的字符,这里n就是结果字符串的长度。 所以我们每次遍历数组,找到右边...

    ShenduCC
  • eclipse如何导入、运行Java SE项目

    在上篇文章介绍了eclipse如何导入、运行Java web项目,本篇文章介绍如何导入、运行Java SE项目,导入Java SE项目比较简单,不像web项目那...

    小诸葛
  • 关于腾讯云校园mysql数据库基础版本无法上传2048kb大小sql文件问题

    https://dev.mysql.com/downloads/file/?id=492745

    不知雨

扫码关注云+社区

领取腾讯云代金券