当图片验证码遇上JSP

今天看到了一个关于使用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的方式区分开来,大大的减轻了代码的逻辑负担,这应该也算是一种比较推崇的方式了吧。希望这次的分享能给看到这篇文章的你一点收获。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值