JSP验证码

来源:互联网 发布:js点击按钮消失又出现 编辑:程序博客网 时间:2024/06/05 15:43

    首先,在web.xml里设置一个servlet,代码如下:

    <servlet>
        
<servlet-name>codeservlet</servlet-name>
        
<servlet-class>test.CodeServlet</servlet-class>
      
</servlet>

      
<servlet-mapping>
        
<servlet-name>codeservlet</servlet-name>
        
<url-pattern>/imgCodeTest</url-pattern>
      
</servlet-mapping>

     然后新建一个包:test,新建一个类:CodeServlet,其代码如下:

package test;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class CodeServlet extends HttpServlet{
    
private static final long serialVersionUID = 1L;

    
private static final String CONTENT_TYPE = "text/html; charset=gb2312";

    
/**
     * 验证码的宽度
     
*/

    
private int width = 70;

    
/**
     * 验证码的高度
     
*/

    
private int height = 20;

    
/**
     * 生成由数字和字母随机组成的图片
     
*/

    
protected void service(HttpServletRequest req, HttpServletResponse resp)
            
throws ServletException, java.io.IOException {
        BufferedImage buffImg 
= new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
        Graphics2D g 
= buffImg.createGraphics();
        
        Random random 
= new Random();                        //生成一个随机数
        g.setColor(Color.BLACK);                            //设置背景颜色
        g.fillRect(00, width, height);                    //填充一个矩形

        Font font 
= new Font("Arial Black", Font.PLAIN, 18);
        g.setFont(font);                                    
//设置字体

        g.setColor(Color.BLUE);
        g.drawRect(
00, width - 1, height - 1);            //绘制边框
        
        g.setColor(Color.BLACK);
        
        
// 随机产生100条干扰线,使图像中的认证码不易被其它程序探测到
        for (int i = 0; i < 100; i++{
            
int x = random.nextInt(width);
            
int y = random.nextInt(height);
            
int x1 = random.nextInt(10);
            
int y1 = random.nextInt(10);
            g.drawLine(x, y, x 
+ x1, y + y1);
        }


        StringBuffer randomCode 
= new StringBuffer();        //用于保存随机产生的验证码
        int red = 0, green = 0, blue = 0;
        
        
// 随机产生四位数的验证码
        for (int i = 0; i < 4; i++{
            
//得到单个验证码
            String strRand = String.valueOf(this.getSignCode(random.nextInt()));
            
            
//随机生成颜色值,使生成的字符验证码颜色各不相同
            red = random.nextInt(200);
            green 
= random.nextInt(200);
            blue 
= random.nextInt(20);
            
            
// 用随机产生的颜色将验证码绘制到图像中
            g.setColor(new Color(red+20, green+20, blue+200));
            g.drawString(strRand, 
15 * i + 816);
            
            
// 将产生的四个随机字符组合在一起
            randomCode.append(strRand);
        }

        
        
// 将四位数字的验证码保存到Session里面
        HttpSession session = req.getSession();
        session.setAttribute(
"checkCode", randomCode.toString());
        
        
// 禁止图像缓存
        resp.setHeader("Prama""no-cache");
        resp.setHeader(
"Coche-Control""no-cache");
        resp.setDateHeader(
"Expires"0);
        resp.setContentType(
"image/jpeg");
        
        
// 将图像输出到Servelt输出流中
        ServletOutputStream sos = resp.getOutputStream();
        ImageIO.write(buffImg, 
"jpeg", sos);
        sos.close();
    }


    
/**
     * 随机生成单个字符
     * 
@param num 随机生成的一个整数
     * 
@return 单个数字或字母
     
*/

    
public char getSignCode(int num) {
        Random random 
= new Random();                    //生成一个随机数
        int scope = 0;                                    //设定生成字符的范围,48为数字,65是大写字母
        char code = ' ';                                //随机生成的单个数字或字母
        
        
if(num % 2 == 0){                                //传递过来的参数是偶数,就生成一个数字
            scope = 48;
            code 
= (char)(scope + random.nextInt(10));    //从0到9中随机生成一个数字            
        }
else{                                            //传递过来的参数是奇数,就生成一个字母
            scope = 65;
            code 
= (char)(scope + random.nextInt(26));    //随机生成一个大写字母
        }

        
        
return code;
    }

    
    
public void doPost(HttpServletRequest request, HttpServletResponse response)
            
throws ServletException, IOException {
        doGet(request, response);
    }


    
public void doGet(HttpServletRequest request, HttpServletResponse response)
            
throws ServletException, IOException {
        response.setContentType(CONTENT_TYPE);
    }

}


    接着,在struts-config.xml里添加Form和Action,代码如下:

<form-bean name="loginForm" type="org.apache.struts.action.DynaActionForm">
            
<form-property name="code" type="java.lang.String"/>
            
<form-property name="username" type="java.lang.String"/>
            
<form-property name="password" type="java.lang.String"/>
        
</form-bean>
<action path="/login" type="test.LoginAction" name="loginForm">
              
<forward name="success" path="/main.jsp"/>
              
<forward name="fail" path="/index.jsp"/>
    
</action>


    在test包里添加一个Action:LoginAction.java,代码如下:

package test;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.DynaActionForm;

public class LoginAction extends Action{
    
public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            
throws Exception {
        String checkCode 
= (String)request.getSession().getAttribute("checkCode");
        DynaActionForm df 
= (DynaActionForm)form;
        
        String username 
= df.getString("username");
        String password 
= df.getString("password");
        String code 
= (String)df.get("code");
        
        
if(!code.equalsIgnoreCase(checkCode)){
            request.setAttribute(
"wrong1","验证码不正确");
            
return mapping.findForward("fail");
        }

        
if(!username.trim().equals("lin"|| !password.trim().equals("123")){
            request.setAttribute(
"wrong2","用户名称或登录密码错误!");
            
return mapping.findForward("fail");
        }


        
return mapping.findForward("success");
    }

}


    最后是两个JSP页面,登录时的页面index.jsp和登录成功页面main.jsp
<%@page contentType="text/html;charset=gb2312"%>
<%@ taglib uri="/tags/struts-bean" prefix="bean"%>
<%@ taglib uri="/tags/struts-logic" prefix="logic"%>
<html>
<head>
<title>验证码 -- 测试</title>
<script>
<!--
function check()
{
    
if(document.form.username.value == "" || document.form.password.value == "")
    
{
        alert(
"用户名或密码不能为空");
        document.form.username.focus();
        
return false;
    }

    document.form.submit();
}

function look() 
{
    
if(event.keyCode==13{    //回车
        check();
    }

}
    
document.onkeydown
=look;
-->
</script>
</head>

<body onload="document.form.username.focus();" bgcolor="#E0F0F8">

<logic:notEmpty name="wrong1" scope="request">
    
<script>
        alert(
"验证码填写错误!");
    
</script>
</logic:notEmpty>
<logic:notEmpty name="wrong2" scope="request">
    
<script>
        alert(
"用户名称或登录密码错误!");
    
</script>
</logic:notEmpty>

  
<table width="100%" align="center" bgcolor="#E0F0F8" cellpadding="0" cellspacing="0">
    
<tr height="40%">
      
<td align="center">
        
<form id="form" name="form" method="post" action="login.do">
        
<table bordercolor="darkkhaki" border="8" width="400" height="180" cellpadding="0" cellspacing="0">
          
<tr>
            
<td align="left" valign="middle">
            
<table width="80%" border="0" align="center" cellpadding="0" cellspacing="3">
              
<tr>
                
<td width="35%"><div align="right">用户名称:</div></td>
                
<td colspan="3"><input name="username" type="text" size="15"/></td>
              
</tr>
              
<tr>
                
<td><div align="right">登陆密码:</div></td>
                
<td colspan="3"><input name="password" type="password" size="15" /></td>
              
</tr>
              
<tr>
                
<td><div align="right">验 证 码:</div></td>
                
<td width="14%"><input name="code" type="text" size="6"/></td>
                
<td width="22%"><div align="left"><img id="redom" src="imgCodeTest"/></div></td>
                
<td width="29%"><div align="left"><a href="#" onclick="javascript:document.getElementById('redom').src='imgCodeTest';">看不清楚</a></div></td>
              
</tr>
              
<tr>
                
<td colspan="4">
                
<div align="center">
                  
<input type="button" value="登    陆" onclick="check();"/>
                
</div>
                
</td>
              
</tr>
            
</table>
            
</td>
          
</tr>
        
</table>
        
</form>
      
</td>
    
</tr>
  
</table>
</body>
</html>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ page language="java" contentType="text/html; charset=gb2312" %>

<html>
<head>
  
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
  
<title>欢迎</title>
</head>
<body bgcolor="#E0F0F8">
<br/>
<br/>
<p align="center" style="height:200px;color:blue;">验证码验证成功!</p>
</body>
</html>


     至此,大功告成!在程序中,只是简单地设定了用户名和密码,没有通过数据库来检测,有意者可以自己添加上去,比较简单。
   
如有问题,请留言给我,大家一起探讨,一起成长!