Struts2生成验证码

Struts2验证码实战指南:Web界面的验证码生成技术 验证码,即 Completely Automated Public Turing test to tell Computers and Humans Apart,是自动化测试手段的一种,用来判断发起请求的是否为真实人类用户。它通过一系列设计,使得计算机难以自动识别,从而达到安全验证的目的。在Struts2框架中,Action作为控制器的角色至关重要,它连接视图(View)和模型(Model),并处理用户请求。验证码生成与验证流程中,Action负责生成验证码图片,并存储验证码答案以便后续验证。 阅读详情
1:Action类
package com.simperfect.action;

import java.io.ByteArrayInputStream;
import java.util.Map;

import org.apache.struts2.interceptor.SessionAware;

import com.opensymphony.xwork2.ActionSupport;
import com.simperfect.tools.randomvalidate.SecurityCode;
import com.simperfect.tools.randomvalidate.SecurityImage;

public class ValidateCodeAction extends ActionSupport implements SessionAware {

     /**
     * 
     */
     private static final long serialVersionUID = 2223970331282695415L;
     private Map<String, Object> session;
     private ByteArrayInputStream imageStream;
     private String flag="";

     public String getValidateImage() {
          String securityCode = new SecurityCode().getDefaultSecurityCode();
          imageStream = new SecurityImage().getImageAsInputStream(securityCode);
          if(flag.equals("login")){
               session.put("LOGINSECURITYCODE", securityCode);
          }else if(flag.equals("reg")){
               session.put("REGSECURITYCODE", securityCode);
          }else if(flag.equals("write")){
               session.put("WRITESECURITYCODE", securityCode);
          }else if(flag.equals("edit")){
               session.put("EDITSECURITYCODE", securityCode);
          }
          return SUCCESS;
     }

     public void setSession(Map<String, Object> arg0) {
          // TODO Auto-generated method stub
          session = arg0;
     }

     public void setImageStream(ByteArrayInputStream imageStream) {
          this.imageStream = imageStream;
     }

     public ByteArrayInputStream getImageStream() {
          return imageStream;
     }

     public void setFlag(String flag) {
          this.flag = flag;
     }

     public String getFlag() {
          return flag;
     }

}
2.验证码相关类
package com.simperfect.tools.randomvalidate;

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.util.Random;

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

/**
* 工具类,生成验证码图片
*/
public class SecurityImage {

     /**
     * 生成验证码图片
     * 
     * @param securityCode
     *            验证码字符
     * @return BufferedImage 图片
     */
     private BufferedImage createImage(String securityCode) {
          // 验证码长度
          int codeLength = securityCode.length();
          // 字体大小
          int fSize = 14;
          int fWidth = fSize + 1;
          // 图片宽度
          int width = codeLength * fWidth + 6;
          // 图片高度
          int height = fSize * 2 + 1;

          // 图片
          BufferedImage image = new BufferedImage(width, height,
                    BufferedImage.TYPE_INT_RGB);
          Graphics g = image.createGraphics();

          // 设置背景色
          g.setColor(Color.WHITE);
          // 填充背景
          g.fillRect(0, 0, width, height);
          // 设置边框颜色
          g.setColor(Color.LIGHT_GRAY);
          // 边框字体样式
          g.setFont(new Font("Arial", Font.BOLD, height - 2));
          // 绘制边框
          g.drawRect(0, 0, width - 1, height - 1);
          // 绘制噪点
          Random rand = new Random();
          // 设置噪点颜色
          g.setColor(Color.LIGHT_GRAY);
          for (int i = 0; i < codeLength * 6; i++) {
               int x = rand.nextInt(width);
               int y = rand.nextInt(height);
               // 绘制1*1大小的矩形
               g.drawRect(x, y, 1, 1);
          }

          // 绘制验证码
          int codeY = height - 10;
          // 设置字体颜色和样式
          g.setColor(new Color(19, 148, 246));
          g.setFont(new Font("Georgia", Font.BOLD, fSize));
          for (int i = 0; i < codeLength; i++) {
               g.drawString(String.valueOf(securityCode.charAt(i)), i * 16 + 5,
                         codeY);
          }
          // 关闭资源
          g.dispose();

          return image;
     }

     /**
     * 返回验证码图片的流格式
     * 
     * @param securityCode
     *            验证码
     * @return ByteArrayInputStream 图片流
     */
     public ByteArrayInputStream getImageAsInputStream(String securityCode) {
          BufferedImage image = this.createImage(securityCode);
          return this.convertImageToStream(image);
     }

     /**
     * 将BufferedImage转换成ByteArrayInputStream
     * 
     * @param image
     *            图片
     * @return ByteArrayInputStream 流
     */
     private ByteArrayInputStream convertImageToStream(BufferedImage image) {
          ByteArrayInputStream inputStream = null;
          ByteArrayOutputStream bos = new ByteArrayOutputStream();
          JPEGImageEncoder jpeg = JPEGCodec.createJPEGEncoder(bos);
          try {
               jpeg.encode(image);
               byte[] bts = bos.toByteArray();
               inputStream = new ByteArrayInputStream(bts);
          } catch (ImageFormatException e) {
               e.printStackTrace();
          } catch (IOException e) {
               e.printStackTrace();
          }
          return inputStream;
     }
}

(2)package com.simperfect.tools.randomvalidate;

import java.util.Arrays;

import com.simperfect.inter.tools.LoggerManager;

public class SecurityCode {
     /**
     * 验证码难度级别,Simple只包含数字,Medium包含数字和小写英文,Hard包含数字和大小写英文
     */
     public enum SecurityCodeLevel {
          Simple, Medium, Hard
     };

     // 字符集合(除去易混淆的数字0、数字1、字母l、字母o、字母O)
     public static final char[] codes = { '2', '3', '4', '5', '6', '7', '8',
               '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm',
               'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A',
               'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
               'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };

     /**
     * 产生默认验证码,4位中等难度
     * 
     * @return String 验证码
     */
     public String getDefaultSecurityCode() {
          return this.getSecurityCode(4, SecurityCodeLevel.Hard, false);
     }

     /**
     * 产生长度和难度任意的验证码
     * 
     * @param length
     *            长度
     * @param level
     *            难度级别
     * @param isCanRepeat
     *            是否能够出现重复的字符,如果为true,则可能出现 5578这样包含两个5,如果为false,则不可能出现这种情况
     * @return String 验证码
     */
     public String getSecurityCode(int length, SecurityCodeLevel level,
               boolean isCanRepeat) {
          // 随机抽取len个字符
          // int len = length;
          // 根据不同的难度截取字符数组
          char[] codeRange = this.getCodeRangeByLevel(level);
          // 字符集合长度
          // int n = codes.length;
          // 抛出运行时异常
          this.checkLenISValidate(length, codeRange.length, isCanRepeat, level);
          // 判断能否出现重复的字符
          return this.getCodeStr(length, isCanRepeat, codeRange);

     }

     private String getCodeStr(int length, boolean isCanRepeat, char[] codeRange) {
          // 存放抽取出来的字符
          char[] result = new char[length];
          int n = codeRange.length;
          for (int i = 0; i < result.length; i++) {
               // 索引 0 and n-1
               int r = (int) (Math.random() * n);

               // 将result中的第i个元素设置为codes[r]存放的数值
               result[i] = codeRange[r];

               // 必须确保不会再次抽取到那个字符,因为所有抽取的字符必须不相同。
               // 因此,这里用数组中的最后一个字符改写codes[r],并将n减1
               if (!isCanRepeat) {
                    codeRange[r] = codeRange[n - 1];
                    n--;
               }
          }
          return String.valueOf(result);
     }

     private char[] getCodeRangeByLevel(SecurityCodeLevel level) {
          char[] result = null;
          switch (level) {
          case Simple:
               result = Arrays.copyOfRange(codes, 0, 7);
               break;
          case Medium:
               result = Arrays.copyOfRange(codes, 0, 31);
               break;
          default:
               result = Arrays.copyOfRange(codes,0,codes.length);
               break;
          }
          return result;
     }

     private void checkLenISValidate(int codeLen, int codesLen,
               boolean isCanRepeat, SecurityCodeLevel level) {
          if (codeLen > codesLen && isCanRepeat == false) {
               LoggerManager.writeLogStr(String.format(
                         "调用SecurityCode.getSecurityCode(%1$s,%2$s,%3$s)出现异常,"
                                   + "当isCanRepeat为%3$s时,传入参数%1$s不能大于%4$s", codeLen,
                         level, isCanRepeat, codesLen), 3);
               throw new RuntimeException(String.format(
                         "调用SecurityCode.getSecurityCode(%1$s,%2$s,%3$s)出现异常,"
                                   + "当isCanRepeat为%3$s时,传入参数%1$s不能大于%4$s", codeLen,
                         level, isCanRepeat, codesLen));
          }
     }
}
3.Struts2配置
       < package name ="Security" extends= "struts-default">
             < action name ="getValidateImage" class= "validateCodeAction"
                   method ="getValidateImage" >
                   < result name ="success" type= "stream">
                         < param name ="contentType" > image/jpeg </param >
                         < param name ="inputName" > imageStream</ param >
                         < param name ="bufferSize" > 2048</ param >
                   </ result>
             </ action>
       </ package>
RC滤波电路工作原理:【带图+公式计算】 容抗Xc和电容C成反比,和频率f也成反比,C越大,交流电容易通过电容,说明电容量大,电容的阻碍作用小;交流电的频率高,交流电也容易通过电容,说明频率高,电容的阻碍作用也小。我们可以看到,一个2V的纹波,经常RC电路后,幅值下降到mv级别,基本可以忽略不计,这就是RC滤波电路的工作原理。一个频率为1Khz的信号,通过一个容值为0.1uf的电容,计算电容对该信号产生的阻抗。将RC滤波器电路中的电阻,取值为1KΩ,电容取值为0.47uf,纹波幅值为2V。从公式1可以看到,Xc越大,Vout值就越接近Vin的值。 阅读详情

相关推荐

【Origin+Python】使用External Python批量出图代码参考2

不使用part2 的代码,自己打开一个origin2022的界面。这里主要介绍一些进阶代码以及使用盗版origin要如何。3 批量绘制相同设置的曲线图。然后就是没有水印的图片了。

zeng001201的博客 1906

Struts2 验证码图片实例

本文分三个步骤介绍验证码图片生成以及与Struts2结合使用。 Step 1.随机验证码   一步一步来,要生成验证码图片,首先要有验证码,然后才能在画在图片上。为了能够灵活控制验证码,特别编写了SecurityCode类,它向外提供随机字符串。并且可以控制字符串的长度和难度。SecurityCode类中提供的验证码分三个难度,易(全数字)、中(数字+小写英文)、难(数字+大小写英文)。难度...

weixin_30375427的博客 202

PSOC Creator 入门教程超详细

最近工作原因需要使用到赛普拉斯的一款芯片,奈何以前没有用过,所以趁这次也学习了一些简单的用法,总结一下,希望能帮到有需要朋友,因为网上关于这方面的文章少的可怜,详细点的更是少之又少!废话少说,正文开始.

qm_mq的博客 5744

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

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; im

夜阑珊的专栏 1049

C++动态规划详解

动态规划思想 一、动态规划概念: 动态规划(dp)是研究多步决策过程最优化问题的一种数学方法。在动态规划中,为了寻找一个问题的最优解(即最优决策过程),将整个问题划分成若干个相应的阶段,并在每个阶段都根据先前所作出的决策作出当前阶段最优决策,进而得出整个问题的最优解。即记住已知问题的答案,在已知的答案的基础上解决未知的问题。 在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后

weixin_51951103的博客 2万+

CubeMX配置ADC+DMA避坑实战:如何避免采样过快导致的系统崩溃

本文针对STM32开发中常见的ADC采样过快导致程序卡死问题,提供了基于CubeMX的实战避坑指南。通过分析ADC与DMA协作机制,详解时钟配置、采样时间、DMA缓冲区长度及中断设置等关键步骤,帮助开发者从源头规避系统崩溃风险,实现稳定可靠的数据采集。

weixin_28273593的博客 323

struts2验证码实现

话不多说直接上代码! jsp中验证码源文件: &lt;a id="ptr" href="javascript:;"&gt;&lt;img height="27px" alt="换一张" src="&lt;%=request.getContextPath() %&gt;/getVerifyCode" id="prtImg"/&gt;&am

286 139

避开封号风险!wxauto+Claude API实现微信智能客服的合规方案

本文详细介绍了如何利用wxauto和Claude API构建合规的微信智能客服系统,避免封号风险。通过技术选型对比、防封策略设计及大模型接入实践,为企业提供了一套安全高效的解决方案,特别适合中小企业在微信生态中部署AI客服。

sql99的博客 445

Struts2 验证码图片生成实例

Step 1.随机验证码 一步一步来,要生成验证码图片,首先要有验证码,然后才能在画在图片上。为了能够灵活控制验证码,特别编写了SecurityCode类,它向外提供随机字符串。并且可以控制字符串的长度和难度。SecurityCode类中提供的验证码分三个难度,易(全数字)、中(数字+小写英文)、难(数字+大小写英文)。难度使用枚举SecurityCodeLevle表示,避免使用1、2、3这样没

shiyuezhong的专栏 1万+

zemax像差参数Ray Fan/Spot Diagram/MTF/....讲解三

zemax像差参数Ray Fan/Spot Diagram/MTF/....讲解三

weixin_72050316的博客 1384

RK3588 部署 YOLO26 目标检测:从环境搭建到 NPU 推理

采集图像(500+ 张,覆盖不同光照和角度)→ 筛选(删除模糊、无目标的图像)→ LabelImg 标注(选择 YOLO 格式)→ 划分 train:val:test = 7:2:1labelImg├── train/├── val/nc: 3类别顺序必须与 LabelImg 标注时一致。YOLO26 在 RK3588 上的部署流程是 PC 端训练 → ONNX 导出(opset=11)→ RKNN 转换(INT8 量化)→ 板端推理。

LXY_LOVE36的博客 416

实验_Struts2实现登陆功能(验证码校验)

Struts2实现登陆功能(验证码校验)1.实验名称 熟悉Struts2核心文件2.实验目的 (1)熟悉Struts2的配置文件web.xml和struts.xml。 (2)熟悉如何书写用户定义的控制器。3.实验内容 实现如下页面中登陆的功能。 要求: 管理员登录后跳到管理员登陆成功的页面 普通用户登录后跳到普通用户登陆成功的页面 登录时用户名密码输入错跳到出错页 注册和登录时

小孤山的博客 6419

C# 的 Dapper 库高级进阶:刨根问底的深度解析

通过今天的探索,我们了解了 Dapper 的一些高级功能,包括如何处理复杂的查询、执行批量操作以及如何优化性能。希望这篇深入浅出的文章能帮助你在实际项目中更好地运用 Dapper!🎈好了,小伙伴们,今天的分享就到这里啦!如果你有任何疑问或者想要分享自己的经验,请在评论区留言。我们下次再见!👋上述示例代码仅供参考,实际使用时请根据项目需求进行适当调整。✨Dapper 官方文档Dapper 性能优化指南Dapper 动态参数使用来同时执行多个查询。利用Execute和Query方法来简化 SQL 调用。

java专栏 812

struts2实现验证码的生成

1、定义一个生成验证码的工具类 package org.qrsx.yang_xuexi.action; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; imp

BeautyOfJava的专栏 1285

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Struts2生成验证码小例子

Struts2生成验证码小例子 众所周知,验证码在互联网中应用非常之广泛,作用也很明确,防止机器人。下面我将详细讲解如何利用struts2来生成验证码: step1:ImageUtil.java 工具类,生产指定大小的图片 package image; import java.awt.Color; import java.awt.Font; import java

龙腾四海365的专栏 687

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

java struts2 验证码_java+Struts2生成验证码

public class VerifyCode {private int w = 70;private int h = 35;private Random r = new Random();// {"宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", "楷体_GB2312"}private String[] fontNames = {"宋体", "华文楷体", ...

weixin_29587015的博客 159

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

struts2生成验证码

思路:用response的输出流向页面输入图片 (1)图片生成工具类 package com.wframe.base.utils; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints

qq576341837的博客 384

java struts2 验证码,struts2中验证码的生成和使用

第一步生产字符串:package com.yancode.demo;import java.util.Arrays;/** 一步一步来,要生成验证码图片,首先要有验证码,然后才能在画在图片上。为了能够灵活控制验证码,* 特别编写了SecurityCode类,它向外提供随机字符串。并且可以控制字符串的长度和难度。* SecurityCode类中提供的验证码分三个难度,易(全数字)、中(数字+小写英文...

weixin_35723352的博客 346

struts2生成登陆验证码

原文地址:http://www.cnblogs.com/dongliyang/archive/2012/08/24/2654431.html Struts2 验证码图片实例 本文分三个步骤介绍验证码图片生成以及与Struts2结合使用。  Step 1.随机验证码   一步一步来,要生成验证码图片,首先要有验证码,然后才能在画在图片上。为了能够灵活控制验证码,特别编写了Secur...

zengshaotao的专栏 255

Struts2实现生成动态验证码并验证实例代码

这篇文章主要介绍了Struts2实现生成动态验证码并验证实例代码的相关资料,非常不错具有参考借鉴价值,需要的朋友可以参考下 一、基本流程: 产生一个验证码页面(很小)→嵌入到表单中→点击可以刷新页面→表单提交时验证。 二、方法: 1、定义TestAction,实现画图方法 package com.zhuguang.action; import java.awt.Color; import ja...

渣渣的夏天 475

java+Struts2生成验证码

public class VerifyCode { private int w = 70; private int h = 35; private Random r = new Random(); // {...

choujuechong4238的博客 177

Struts2 验证码图片生成实例]

Struts2 验证码图片生成实例 ] Step 1.随机验证码 一步一步来,要生成验证码图片,首先要有验证码,然后才能在画在图片上。为了能够灵活控制验证码,特别编写了SecurityCode类,它向外提供随机字符串。并且可以控制字符串的长度和难度。SecurityCode类中提供的验证码分三个难度,易(全数字)、中(数字+小写英文)、难(数字+大小写英文)。难度使用枚举Secu

gaoqiao1988的专栏 777

java struts2 验证码_Struts2实现生成动态验证码并验证实例代码

一、基本流程:产生一个验证码页面(很小)→嵌入到表单中→点击可以刷新页面→表单提交时验证。二、方法:1、定义TestAction,实现画图方法package com.zhuguang.action;import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.image.BufferedIma...

weixin_35645652的博客 271

struts2生成中文验证码的Action

importjava.io.IOException; importjava.util.Map; importorg.apache.struts2.interceptor.SessionAware; importcn.gx80.service.util.ValidateImageService; importcn.gx80.util.Key; /** *生成验证码

大齐的学习笔记 87

Struts2生成登录验证码

1: jsp 页面.&lt;s:url action="va_ValidateImage" namespace="/user" id="validate"&gt;&lt;/s:url&gt;&lt;img alt="F5刷新" src="${validate}" id="codeimg" style="width: 70px; heigh

jamen001的博客 207

Struts2验证码的生成

1.1 创建Web Project工程   1.1.1  引入jar文件   1.1.2  配置核心控制器web.xml <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:sche

疯狂代码的专栏 564
上一篇: 用ajaxFileUpload上传附件时,总是跳转到error函数
下一篇: 利用lightbox弹出带遮罩层的弹出框
小马pony
博客等级 码龄14年 11粉丝 62原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值