基于struts2框架下的验证码实现

本文详细介绍了如何使用Struts2框架构建一个包含验证码功能的系统,包括验证码图片生成、验证流程及安全性考虑。通过在com.itany.util下创建IdentifyCodeUtil类实现验证码图片生成,BaseAction类作为基类实现请求响应,ImageAction类生成验证码图片,SecurityAction类验证用户输入的验证码。此外,通过struts.xml配置文件整合Struts2框架,实现了验证码系统的无缝集成。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、配置struts2框架

2、在com.itany.util下新建文件   IdentifyCodeUtil.java

package com.itany.util;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;

import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

public class IdentifyCodeUtil
{
    // 随机产生的验证码字符都是从下面的字符串中获取的
    private String s = "0123456789abcdefghijklmnopqrstuvwxyz";
    
    // 图片的字节流
    private InputStream imageStream;
    
    // 验证码图片对应的验证码字符串
    private String identifyCode;
    
    // 私有的构造方法
    private IdentifyCodeUtil()
    {
        init();
    }
    
    public InputStream getImageStream()
    {
        return imageStream;
    }
    
    public String getIdentifyCode()
    {
        return identifyCode;
    }
    
    public static IdentifyCodeUtil Instance()
    {
        return new IdentifyCodeUtil();
    }
    
    private void init()
    {
        int width, height;
        width = 100;// 图片宽度
        height = 30;// 图片高度
        // 在内存中创建图片对象,宽度为width,高度为height
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 获取图形上下文
        Graphics graphics = image.getGraphics();
        // 设置图片背景色
        graphics.setColor(Color.WHITE);
        // 填充背景色
        graphics.fillRect(0, 0, width, height);
        
        graphics.setColor(Color.DARK_GRAY);
        // 设置字体
        graphics.setFont(new Font("宋体", Font.BOLD + Font.ITALIC, 30));
        
        // 生成随机类
        Random random = new Random();
        // 生成长度为5位的字符串,并放入sb中
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 5; i++)
        {
            int index = random.nextInt(s.length());
            sb.append(s.charAt(index));
            // 将认证码显示到图象中
            graphics.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
            // 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
            graphics.drawString(s.charAt(index) + "", 15 * i + 6, 25);
        }
        // 重新设置字体的颜色,使其与线条的颜色不同
        graphics.setColor(getRandColor(170, 250));
        // 先设置线条的颜色,再随机产生120条干扰线,使图象中的认证码不易被其它程序探测到
        graphics.setColor(getRandColor(120, 200));
        for (int i = 0; i < 120; i++)
        {
            int x = random.nextInt(width);// 每条线条的起点坐标
            int y = random.nextInt(height);
            int xl = random.nextInt(12);
            int yl = random.nextInt(12);
            graphics.drawLine(x, y, x + xl, y + yl);
        }
        
        this.identifyCode = sb.toString();
        
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bos);
        
        try
        {
            encoder.encode(image);
        }
        catch (ImageFormatException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        
        this.imageStream = new ByteArrayInputStream(bos.toByteArray());
    }
    
    /*
     * 给定范围获得随机颜色
     */
    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);
    }
}


3、在包   com.itany.action 下新建文件 BaseAction.java

package com.itany.action;

import java.util.Map;

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

import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;
import org.apache.struts2.util.ServletContextAware;

import com.opensymphony.xwork2.ActionSupport;

public class BaseAction extends ActionSupport implements ServletRequestAware, ServletResponseAware, ServletContextAware, SessionAware
{
    
    protected HttpServletRequest request;
    
    protected HttpServletResponse response;
    
    protected ServletContext application;
    
    protected Map<String, Object> session;
    
    public void setServletRequest(HttpServletRequest request)
    {
        this.request = request;
    }
    
    public void setServletResponse(HttpServletResponse response)
    {
        this.response = response;
    }
    
    public void setServletContext(ServletContext application)
    {
        this.application = application;
    }
    
    public void setSession(Map<String, Object> session)
    {
        this.session = session;
    }
    
}


 

4、在包   com.itany.action 下新建文件 ImageAction.java

package com.itany.action;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Random;

import com.itany.util.IdentifyCodeUtil;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import org.apache.struts2.json.annotations.JSON;

public class ImageAction extends BaseAction
{
    
    private InputStream imageStream;
    
    /* private String s = "0123456789abcdefghijklmnopqrstuvwxyz"; */
    
    public InputStream getImageStream()
    {
        return imageStream;
    }
    
    public void setImageStream(InputStream imageStream)
    {
        this.imageStream = imageStream;
    }
    
    @Override
    public String execute()
        throws Exception
    {
        IdentifyCodeUtil icu = IdentifyCodeUtil.Instance();
        session.put("code", icu.getIdentifyCode());
        imageStream = icu.getImageStream();
        return SUCCESS;
    }
}


 

5、在包   com.itany.action 下新建文件 SecurityAction.java

package com.itany.action;

import javax.servlet.ServletOutputStream;

import org.apache.struts2.json.annotations.JSON;

public class SecurityAction extends BaseAction
{
    private String info;
    
    public SecurityAction()
    {
        super();
    }
    
    public String getInfo()
    {
        return info;
    }
    
    public void setInfo(String info)
    {
        this.info = info;
    }
    
    @Override
    public String execute()
        throws Exception
    {
        String code = (String)session.get("code");
        if (code.equals(info))
        {
            info = "true";
            return SUCCESS;
        }
        else
        {
            info = "false";
            return SUCCESS;
        }
    }
}


 

6、在src下面配置struts文件struts.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN" "http://struts.apache.org/dtds/struts-2.1.7.dtd" >
<struts>

	<package name="result" namespace="/result" extends="struts-default">
		<result-types>
			<result-type name="json" class="org.apache.struts2.json.JSONResult" />
		</result-types>
		<action name="image" class="com.itany.action.ImageAction">
			<result type="stream">
				<param name="inputName">imageStream</param>
			</result>
			<result name="fail" type="redirect">/fail.jsp</result>
		</action>
		<action name="security" class="com.itany.action.SecurityAction">
			<result type="json">
				<param name="root">info</param>
			</result>
		</action>
	</package>

</struts>


 

7、在WEB-ROOT下新建image.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags"%> <html> <head> <script type="text/javascript" src="js/jquery-1.4.min.js"></script> <script type="text/javascript">  var timer2 = null;  var num = 0;  function changeImage() {   var img = document.getElementById("img");   img.src = "${pageContext.request.contextPath}/result/image.action?a="     + new Date().getTime();   return false;//因为是用onclik触发,所以为了防止跳转,此处用false  }  function h(info) {   //$("#message").html("正在验证......");   timer2 = window.setInterval("show()", 250);//每隔0.25秒执行一次show()方法   $     .post(       "${pageContext.request.contextPath}/result/security.action",       {        "info" : info       },       function(data) {        if (data == "true") {         $("#message")           .html(             "<img style='vertical-align:top;' src='image/success.png' />验证码输入正确");         isImageCodeRight = true;         window.clearInterval(timer2);//清除已设置的setInterval对象        } else {         $("#message")           .html(             "<img style='vertical-align:top;' src='image/fail.png' />验证输入错误");         isImageCodeRight = false;         window.clearInterval(timer2);//清除已设置的setInterval对象        }

      });  }  function show() {   var info = "正在验证";   for ( var i = 0; i < num; i++) {    info = info + ".";   }   if (num < 6) {    num = num + 1;   } else {    num = 0;   }   $("#message").html(info);  } </script> </head> <body>  验证码:  <a href="javascript:;" onclick="return changeImage();"><img   id="img" src="${pageContext.request.contextPath }/result/image.action"   title="点击图片刷新验证码" style="border: solid 2px red" /></a>  <br />  <input type="text" name="code" id="code" onblur="h(this.value);" />  <span id="message" style="color: red;"></span> </body> </html>


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值