今天看到了一个关于使用JSP方式生成图片验证码 的小例子,感觉真的是很不错,拿来分享一下。

原理

对于图片验证码,我们在审查元素的时候会方便的看出是<img src="#" />标签,其指向 的也仅仅是一个资源而已,所以我们既可以为其指定一个链接,也可以使用图片生成的方式实现。那么,今天就来生成吧!

代码

先来看一下门户,Login.html 网页的书写

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>For User Login</title>
</head>
<body>

    <form action="TestCheckCode.jsp" name="login" method="post">

        <table align="center">
            <tr>
                <td align="right">Username:</td>
                <td><input type="text" name="username" value="" size="15" /></td>
            </tr>
            <tr>
                <td align="right">Password:</td>
                <td><input type="password" name="password" value="" size="15" /></td>
            </tr>

            <tr>
                <td align="right">Check Code:</td>
                <td><input type="text" name="checkcode" value="" size="15" />
                    <img alt="" src="getImageCode.jsp"></td>
            </tr>
            <tr>
                <td align="center"><input type="submit" value="Login" size="15" /></td>
                <td><a href="Login.html">Change a Check Code</a></td>
            </tr>

        </table>

    </form>

</body>
</html>

然后是action中对应的那个文件TestCheckCode.jsp,作用不言而喻就是检查验证码是否正确的逻辑了。

<%@ 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">
<title>User Login Check</title>
</head>
<body>
    <%
        Object obj = session.getAttribute("SavedCheckCode");
        if (obj == null) {
            response.sendRedirect("/Login.html");
        } else {

            String username = request.getParameter("username");
            String password = request.getParameter("password");
            String checkcode = request.getParameter("checkcode");
            out.println("The Info you typed are:");
            out.println("Username : " + username);
            out.println("Password : " + password);
            out.println("Check Code : " + checkcode);
            if (checkcode.equals(obj)) {
                out.println("Login Success!");
            } else {
                out.println("Login Failed!<br>" + "The true Check Code is " + obj.toString());
            }

            session.removeAttribute("SavedCheckCode");
        }
    %>
</body>
</html>

相信你也看到了,最核心的部分就在于Object obj = session.getAttribute("SavedCheckCode");。这个值是怎么放到session里面的呢?这就要归功于session这个存储域本身强大的特点了。保存了会话期间的所有的信息。好了,下面看一看验证码的生成吧。getImageCode.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.awt.*,java.awt.image.*,javax.imageio.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%
    //设置浏览器不缓存图片,这一点还是很有必要的
    response.setHeader("Expires", "0");
    String oldChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";
    String[] codeChars = new String[5];
    String saveCode = "";
    for(int n = 0 ; n < 5 ; n++) {
        int index = (int)(35* Math.random());
        codeChars[n] = "" + oldChars.charAt(index);
        saveCode += codeChars[n];
    }
    session.setAttribute("SavedCheckCode", saveCode);

    BufferedImage bi = new BufferedImage(80,20,BufferedImage.TYPE_USHORT_555_RGB);
    Graphics g = bi.getGraphics();
    g.setColor(Color.LIGHT_GRAY);
    g.fillRect(0,0,80,20);
    g.setColor(Color.BLACK);
    g.setFont(new Font("Monotype Corsiva",Font.ITALIC,18));
    g.drawString(codeChars[0], 1,15);
    g.drawString(codeChars[1], 16,13);
    g.drawString(codeChars[2], 31,18);
    g.drawString(codeChars[3], 46,14);
    g.drawString(codeChars[4], 61,15);
    g.dispose();

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ImageIO.write(bi, "jpeg", baos);
    byte[] imagebyte = baos.toByteArray();

    response.setContentLength(imagebyte.length);
    response.setContentType("image/jpeg");
    ServletOutputStream imgout = response.getOutputStream();
    imgout.write(imagebyte);
    baos.close();
    imgout.close();

%>

这样,每次访问一下Login.html界面的时候都会引起session内验证码值的变化,这样也算是符合了我们的需求了。

关键点

这里面对于JSP部分,重要的其实没什么,就一个session可以作为存储域的特点,而对于生成图片验证码的部分,着实是最重要的了。下面我就来谈谈我对这部分的理解。

首先是先获得图片验证码,这是基础嘛,获得之后存储到我们的session域内,方便之后的取出使用

//设置浏览器不缓存图片,这一点还是很有必要的
    response.setHeader("Expires", "0");
    String oldChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";
    String[] codeChars = new String[5];
    String saveCode = "";
    for(int n = 0 ; n < 5 ; n++) {
        int index = (int)(35* Math.random());
        codeChars[n] = "" + oldChars.charAt(index);
        saveCode += codeChars[n];
    }
    session.setAttribute("SavedCheckCode", saveCode);

然后就是将获得的这个图片验证码以图片的 方式反馈给客户端对象(也就是Login.html的img标签内的src属性。这样也照应了咱之前说过的用代码生成的方式了不是。这里也是Java基础相关的知识了,代码如下:

BufferedImage bi = new BufferedImage(80,20,BufferedImage.TYPE_USHORT_555_RGB);
    Graphics g = bi.getGraphics();
    g.setColor(Color.LIGHT_GRAY);
    g.fillRect(0,0,80,20);
    g.setColor(Color.BLACK);
    g.setFont(new Font("Monotype Corsiva",Font.ITALIC,18));
    g.drawString(codeChars[0], 1,15);
    g.drawString(codeChars[1], 16,13);
    g.drawString(codeChars[2], 31,18);
    g.drawString(codeChars[3], 46,14);
    g.drawString(codeChars[4], 61,15);
    g.dispose();

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ImageIO.write(bi, "jpeg", baos);
    byte[] imagebyte = baos.toByteArray();

    // 设置反馈的类型信息,方便浏览器的解析操作
    response.setContentLength(imagebyte.length);
    response.setContentType("image/jpeg");
    ServletOutputStream imgout = response.getOutputStream();
    imgout.write(imagebyte);
    baos.close();
    imgout.close();

好了,这就算是完成了。使用JSP方式生成图片验证码的好处不仅在于放置用户端JavaScript代码的实效,还能高效的将访问的用户之间以Session的方式区分开来,大大的减轻了代码的逻辑负担,这应该也算是一种比较推崇的方式了吧。希望这次的分享能给看到这篇文章的你一点收获。

当图片验证码遇上JSP的更多相关文章

  1. Webform 文件上传、 C#加图片水印 、 图片验证码

    文件上传:要使用控件 - FileUpload 1.如何判断是否选中文件? FileUpload.FileName - 选中文件的文件名,如果长度不大于0,那么说明没选中任何文件 js - f.val ...

  2. 在linux上使用tomcat服务器图片验证码不显示问题

    背景描述:在liunx系统上,使用tomcat中间件,访问web项目,登录页面的图片验证码显示不出来,但是在window系统上可以正常显示 解决方案:设置一下这个文件tomcat/bin/catali ...

  3. django文件上传、图片验证码、抽屉数据库设计

    1.Django文件上传之Form方式 settings.py, ALLOWED_HOSTS = ['*'] INSTALLED_APPS = [ 'django.contrib.admin', 'd ...

  4. 原生XMLHTTPResponse,jQuery-Ajax 上传文件;iframe上传图片&预览;图片验证码小案例

    原生AJAX Ajax主要就是使用 [XmlHttpRequest]对象来完成请求的操作,该对象在主流浏览器中均存在(除早起的IE),Ajax首次出现IE5.5中存在(ActiveX控件) 1.Xml ...

  5. 图片验证码(Struts2中使用)

    写在前面: 最近在项目中做了一个登录页面,用到了图片验证码的功能,所以记录一下.方便之后再有用到,直接拿来用即可.其实图片验证码的生成都是有固定步骤的,网上也有很多的例子,有的时候,如果不想深究,都是 ...

  6. Django(九)下:Ajax操作、图片验证码、KindEditor使用

    三.Ajax操作 ajax操作基于浏览器的xmlHttpRequest对象,IE低版本是另外一个对象,jQuery 1 版本对那两个对象做了封装,兼容性最好,2 .3版本不再支持IE低版本了. Aja ...

  7. Day24-Ajax操作、图片验证码、KindEditor使用-转

    参考源:http://blog.csdn.net/fgf00/article/details/54917439 三.Ajax操作 ajax操作基于浏览器的xmlHttpRequest对象,IE低版本是 ...

  8. JavaWeb开发之普通图片验证码生成技术与算术表达式验证码生成技术

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6134649.html    另:算术验证码生成的JSP.Servlet实现均已移植github:https:/ ...

  9. Python开发【Django】:图片验证码、KindEditor

    图片验证码 生成图片验证码需要以下: session check_code.py(依赖:Pillow,字体文件) 模块安装 pip install Pillow src属性后面加? 在utils下拷贝 ...

随机推荐

  1. WiFi认证中HTTPS重定向

    问题描述 在引入WiFiDog实现上网认证功能中,有2个绕不过的问题:https重定向和Select检测问题,前者非要求用户访问80端口,后者导致效率较低下.就用户体验来说,https无法主动重定向非 ...

  2. Unix文件系统的主要特点是什么?

    1.  树型层次结构 2.  可安装拆卸的文件系统 3.  文件是无结构的字符流式文件 4.  Unix文件系统吧外部设备和文件目录作为文件处理

  3. vue+cordova 构建hybrid app

    配了一个 vue + cordova + ionicCli 的 项目 支持 ionic 的脚手架命令 支持 cordova 的 插件 安装使用 支持 webpack 的自动构建 vue 安装了 vue ...

  4. day04 Java Web 开发入门

    day04 Java Web 开发入门 1. web 开发相关介绍 2. web 服务器 3. Tomcat服务器启动的问题 4. Tomcat目录结构 5. Web应用程序(虚拟目录映射,缺省web ...

  5. HTML Parsing Error: Unable to modify the parent container element before the child element is closed (KB927917)

    IE8报错误: 用户代理: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .N ...

  6. li标签中list-style-image如何居中

    使用list-style-image设置了一个列表项的小图标时,一直不能让图标居中的显示. 解决办法是:使用ul li的backgrou-image(背景图片)来设置. 代码如下: ul li{ he ...

  7. Spring + Mybatis 集成原理分析

    由于我之前是写在wizNote上的,迁移过来比较浪费时间,所以,这里我直接贴个图片,PDF文件我上传到百度云盘了,需要的可直接下载. 地址:https://pan.baidu.com/s/12ZJmw ...

  8. 关于java的Synchronized,你可能需要知道这些(下)

    上一篇文章介绍了synchronized的基本使用方法和实现,在实现部分说明了synchronized的底层实现依赖系统互斥锁mutex,但是这个一个重型锁,竞争导致线程阻塞挂起,后续拿到锁后再恢复线 ...

  9. MLDS笔记:Optimization

    当函数空间覆盖到目标函数时,如何通过优化调整神经网络的参数找到这个目标函数呢? 深度学习中的损失函数是非凸的,非凸优化是个NP-hard问题,如何通过梯度下降来解决这个问题呢? 注意,不同于learn ...

  10. Node.js 实用工具

    稳定性: 4 - 锁定 这些函数都在'util' 模块里.使用 require('util') 来访问他们. util 模块原先设计的初衷是用来支持 node 的内部 API 的.这里的很多的函数对你 ...