JSP JavaWEB 验证码的实现 基于struts验证码实现

验证码的作用和实现

验证码的作用,很常见的就是登录与注册,或者在贴吧,一些BBS等多处用于防止恶意攻击的。So,web开发者应该学会验证码的设计和实现,我们在开发web项目的时候,当涉及到登录,注册等功能时,我应该采用验证码技术,防止我我们开发的项目是相对于没有验证码的安全点。验证码只是防止机器的批量等暴力攻击,如果是Hacker,那验证码也只是炮灰了 ^—^。

验证码的实现过程:四个步骤搞定~

(由于小弟最近在学习struts,所以本次验证码实现是基于struts的)

一,既然是在struts下开发项目,自然先配置web.xml文件,配置一次就基本没事了。

先在lib下添加以下架包:

commons-fileupload-1.2.1.jar

freemarker-2.3.15.jar

ognl-2.7.3.jar

struts2-core-2.1.8.jar

xwork-core-2.1.6.jar

  • web.xml:
  • <?xml version="1.0" encoding="UTF-8"?>
  • <web-app version="2.5"
  • xmlns="http://java.sun.com/xml/ns/javaee"
  • xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  • xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  • http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  • <welcome-file-list>
  • <welcome-file>index.jsp</welcome-file>
  • </welcome-file-list>
  • <filter>
  • <filter-name>struts2</filter-name>
  • <filter-class>
  • org.apache.struts2.dispatcher.ng.filter.
  • StrutsPrepareAndExecuteFilter
  • </filter-class>
  • </filter>
  • <filter-mapping>
  • <filter-name>struts2</filter-name>
  • <url-pattern>/*</url-pattern>
  • </filter-mapping>
  • </web-app>

以上struts的web.xml配置可以先不管,这个配置是固定的,配置一次就不用再管了。

二,写一个VaildateCodeAction如下:

  • package edu.nwsuaf.xc.action;
  • import java.awt.image.BufferedImage;
  • import java.io.IOException;
  • import java.io.InputStream;
  • import java.util.Map;
  • import org.apache.struts2.interceptor.SessionAware;
  • import edu.nwsuaf.xc.util.ValidateCodeUtil;
  • /**
  • * @author tony
  • * 2014-12-23
  • * 自定义一个Action,并实现SessionAware,需要使用到session保存验证码。
  • */
  • public class VaildateCodeAction implements SessionAware {
  • // 定义一个session为接口注入
  • protected Map<String, Object> session;
  • // 因为需要将上生成的验证码输出到页面 定义一个输入流
  • private InputStream validateCodeStream;
  • public String execute() {
  • // 生成验证码及图片

Map<String, BufferedImage> valiCodeImag = ValidateCodeUtil.getValidateCode();

  • // 验证码
  • String valiCode = valiCodeImag.keySet().iterator().next();
  • session.put("valiCode", valiCode);
  • // 转为输入流
  • BufferedImage image = valiCodeImag.get(valiCode);
  • try {
  • validateCodeStream = ValidateCodeUtil.getAsInputStream(image);
  • } catch (IOException e) {
  • e.printStackTrace();
  • return "error";
  • }
  • return "success";
  • }
  • public InputStream getImageStream() {
  • return validateCodeStream;
  • }
  • public void setImageStream(InputStream imageStream) {
  • this.validateCodeStream = imageStream;
  • }
  • /**
  • * 实现SessionAware接口为Action注入一个session来 保存验证码
  • */
  • public void setSession(Map<String, Object> arg0) {
  • this.session = arg0;

}

}

三,在struts.xml配置文件中配置VaildateCodeAction如下:

  • 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="login" namespace="/login" extends="struts-default">
  • <!-- 直接跳转到登录页面 -->
  • <action name="toLogin">
  • <result name="success">/login.jsp</result>
  • </action>
  • <!-- 生成验证码Action -->
  • <action name="getValidateCode"
  • class="edu.nwsuaf.xc.action.VaildateCodeAction">
  • <result name="success" type="stream">
  • <param name="inputName">imageStream</param>
  • </result>
  • <result name="error">/error.jsp</result>
  • </action>
  • </package>
  • </struts>

另外还有一个验证码的工具类ValidateCodeUtil ,进行封装便于维护,也体现了Java的编程思想。

  • package edu.nwsuaf.xc.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.HashMap;
  • import java.util.Map;
  • import java.util.Random;
  • import com.sun.image.codec.jpeg.JPEGCodec;
  • import com.sun.image.codec.jpeg.JPEGImageEncoder;
  • public final class ValidateCodeUtil {
  • // 验证码的字符来源
  • private static final char[] chars =
  • { ‘0‘, ‘1‘, ‘2‘, ‘3‘, ‘4‘, ‘5‘, ‘6‘, ‘7‘, ‘8‘, ‘9‘, ‘A‘, ‘B‘, ‘C‘, ‘D‘,‘E‘,
  • ‘F‘, ‘G‘, ‘H‘, ‘I‘, ‘J‘, ‘K‘, ‘L‘, ‘M‘,‘N‘, ‘O‘, ‘P‘, ‘Q‘, ‘R‘, ‘S‘, ‘U‘,
  • ‘V‘, ‘W‘, ‘X‘, ‘X‘, ‘Y‘, ‘Z‘, ‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘, ‘f‘, ‘g‘, ‘h‘, ‘i‘, ‘j‘,
  • ‘k‘, ‘l‘, ‘m‘, ‘n‘, ‘o‘, ‘p‘,‘q‘, ‘r‘, ‘s‘, ‘u‘, ‘v‘, ‘w‘, ‘x‘, ‘x‘, ‘y‘, ‘z‘ };
  • // 验证码的字符个数
  • private static final int VALIDATE_SIZE = 5;
  • // 验证码的宽高
  • private static final int WIDTH = 130;
  • private static final int HEIGHT = 45;
  • // 验证码的字体大小
  • private static final int FONT_SIZE = 35;
  • private static Random ran = new Random();
  • public static Map<String, BufferedImage> getValidateCode() {
  • // 存放验证码字符串
  • StringBuffer validate_code = new StringBuffer();
  • BufferedImage blackground = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
  • Graphics graphic = blackground.getGraphics();
  • graphic.setColor(Color.LIGHT_GRAY);
  • graphic.fillRect(0, 0, WIDTH, HEIGHT);
  • // 画随机字符
  • for (int i = 1; i <= VALIDATE_SIZE; i++) {
  • int r = ran.nextInt(chars.length);
  • graphic.setColor(getRandomColor());
  • // 设置画笔的字体和大小
  • graphic.setFont(new Font(null, Font.BOLD + Font.ITALIC, FONT_SIZE));
  • graphic.drawString(chars[r] + "", (i - 1) * WIDTH / VALIDATE_SIZE, 35);
  • // 将字符保存
  • validate_code.append(chars[r]);
  • }
  • // 画干 5 条扰线
  • for (int i = 1; i <= 5; i++) {
  • graphic.setColor(getRandomColor());
  • graphic.drawLine(ran.nextInt(WIDTH), ran.nextInt(HEIGHT),
  • ran.nextInt(WIDTH), ran.nextInt(HEIGHT));
  • }
  • Map<String, BufferedImage> map = new HashMap<String, BufferedImage>();
  • map.put(validate_code.toString(), blackground);
  • return map;
  • }
  • /**
  • * 随机获取颜色
  • * @return
  • */
  • private static Color getRandomColor() {
  • return new Color(ran.nextInt(256), ran.nextInt(256), ran.nextInt(256));
  • }
  • /**
  • * 将图片转化为流
  • * @param image
  • * @return
  • * @throws IOException
  • */

public static InputStream getAsInputStream(BufferedImage image) throws IOException {

  • // ByteArrayOutputStream 自动增长的byte缓冲区
  • ByteArrayOutputStream baos = new ByteArrayOutputStream();
  • JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(baos);
  • encoder.encode(image);
  • byte[] imageBts = baos.toByteArray();
  • InputStream inStream = new ByteArrayInputStream(imageBts);
  • return inStream;
  • }
  • }

其实对于验证码这种比较“孤立”的组件,我们在开发时,写一次的源码的实现,即可保存下来,下次当我们有遇到需要实现验证码功能时,直接copy来用,岂不是大大的提高开发效率。

四,login.jsp页面如下:(实现点击验证码更换验证码)

  •         login.jsp:
  • <%@ page language="java"  pageEncoding="UTF-8"%>
  • <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  • <html>
  • <head>
  • <meta http-equiv="pragma" content="no-cache">
  • <meta http-equiv="cache-control" content="no-cache">
  • <meta http-equiv="expires" content="0">
  • <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
  • <meta http-equiv="description" content="This is my page">
  • <script type="text/javascript" language="javascript">
  • function change(imageObj) {
  • imageObj.src = "login/getValidateCode?date="
  • + new Date().getTime();
  • }
  • </script>
  • </head>
  • <body>
  • <div>
  • 验证码:<input name="" type="text"/>
  • <img alt="验证码" title="点击更换"
  • src="login/getValidateCode.action" onclick="change(this);">
  • </div>
  • </body>
  • </htm

目录结构如图:

测试: 输入http://ip:port/webNamePath

打开浏览器输入 http://localhost:8089/ValidateCode/login/toLogin.action

................

  • Struts的前端控制器FC的配置;
    web.xml的简单配置;
    struts.xml的简单配置;
    验证码的实现工具类Util  。
时间: 2024-10-18 10:25:54

JSP JavaWEB 验证码的实现 基于struts验证码实现的相关文章

基于struts 2.3的家政服务平台V2.0粉色主题-java家政服务平台家政网mysql

基于struts 2.3的家政服务平台V2.0粉色主题-java家政服务平台家政网mysql数据源 1.包含源程序,数据库脚本.2.课题设计仅供参考学习使用,可以在此基础上进行扩展完善.开发环境:Eclipse ,MySQL 5.1,JDK1.7,Tomcat 7涉及技术点:MVC模式.JavaWeb.Struct.JDBC.HTML.CSS.JQUERY.Maven.C3P0.分页.文件上传.购物车等.实现功能:充值.购买歌曲.poi数据导入导出.歌曲上传下载.歌曲播放.用户注册登录注销,管理

基于Struts+Hibernate开发过程中遇到的错误

1.import  javax.servlet.http.HttpServletRequest 导入包出错 导入包出错,通常是包未引入,HttpServletRequest包是浏览器通过http发出的请求, 需要将tomcat/lib 目录下的 servlet-api.jar导入.但是导入后仍然不行,重启eclipse也无法让他生效 最后通过 project -clean来生效的. 2.JSP界面中加入了form标签后就报错 解决办法:将tomcat/lib目录下的el-api,ecj-4.3.

PHPWind9.0 手动屏蔽验证码,解决后台关闭验证码但是依然显示的问题

!!转载麻烦先通知本人,谢谢. 最近在设计一款产品,需要POST登录PHPWind,然而众所周知,PHPWind9(以下简称pw9)自身拥有安全策略,详情各位可以自己去phpwind官方论坛看.安全策略的存在会导致即便站长关闭验证码策略依然在登陆时会显示验证码(前提是该用户重试太多次). 要POST登录,并且不需要验证码,就得处理这个问题,然而官方并没有提供解决的方案,只能依赖自己处理. 首先要明白,phpwind不像众多简单的php程序一般只是简单的该页面代码放置于对应文件中,每一次访问都会调

Jsp标签字典开发_基于Spring+Hibernate

目录 1. Jsp标签字典开发_基于Spring+Hibernate 1.1. 简述 1.2. 定义DictItem实体 1.3. 定义字典的@interface 1.4. 定义字典缓存类 1.5. 定义tld标签 1.6. 持久层实体使用注解 1.7. 页面调用jsp标签 2. 补充点 2.1. Hibernate设置属性成功后扫描字典 2.2. Annotation注解 2.2.1. 简述 2.2.2. 元注解 2.2.3. 自定义注解 1. Jsp标签字典开发_基于Spring+Hiber

Python 爬虫入门(四)—— 验证码上篇(主要讲述验证码验证流程,不含破解验证码)

本篇主要讲述验证码的验证流程,包括如何验证码的实现.如何获取验证码.识别验证码(这篇是人来识别,机器识别放在下篇).发送验证码.同样以一个例子来说明.目标网址 http://icp.alexa.cn/index.php(查询域名备案信息) 1.验证码的实现: 简单的说,验证码就是一张图片,图片上有字符串.网站是如何实现的呢?有WEB基础的人可能会知道,每个浏览器基本都有cookie,作为这次回话的唯一标示.每次访问网站,浏览器都会把这个cookie发送给服务器.验证码就是和这个cookie绑定到

验证码的认识和简单验证码的攻防

验证码(CAPTCHA)一词,几乎是上网的人都接触过.通俗地将,验证码就是一种把坐在电脑前的人类与机器区分开来的测试,也算是一种最常见反图灵测试.一般来说,验证码由计算机生成,服务器端的计算机知道答案,但在网线这端,应该只有用户(即真正的人)知道答案,而计算机不知道. 从上面的定义里,易得: 验证码应该是不易被计算机识别或破解出来的,如果用简单的算法,也能得到极高的破解率(大于或接近于75%),则这个验证码不算一个合格的验证码. 要攻破验证码,最好的方法应该是机器学习,因为这个方法能让计算机模拟

Java生成验证码(包含gif动画验证码)

1.验证码抽象类import java.awt.*;import java.io.OutputStream; import static Randoms.num;import static Randoms.alpha; * <p>验证码抽象类,暂时不支持中文</p> * @author: wuhongjun * @version:1.0public abstract class Captcha protected Font font = new Font("Verdana

【转】前端验证码倒计时、后台发送验证码、创蓝短信接口

前端代码:倒计时 <!DOCTYPE html><html><head lang="en">    <meta charset="UTF-8">    <title></title> <style>        .yanzm_b_btn {            width: 98px;            height: 40px;            float: left

第二十三节:scrapy爬虫识别验证码(二)图片验证码识别

图片验证码基本上是有数字和字母或者数字或者字母组成的字符串,然后通过一些干扰线的绘制而形成图片验证码. 例如:知网的注册就有图片验证码 首先我们需要获取验证码图片,通过开发者工具我们可以得到验证码url链接 其次就是通过Pillow类库和tesserocr进行识别,代码如下: 1 # -*- coding:utf-8 -*- 2 import tesserocr 3 from PIL import Image 4 import requests 5 6 # 通过url链接获取验证码图片,并写入本