`
tianmingqi
  • 浏览: 117512 次
  • 性别: Icon_minigender_1
  • 来自: 河南郑州
社区版块
存档分类
最新评论

struts2 实现图片验证码

阅读更多

今天在struts2下实现了图片验证码的实例,基本思想如下:

1.实现产生图片验证码的action(其实产生图片的过程不应该在action里,这里为了方便全写在action里了)。

public class RandomAction extends ActionSupport{
	private ByteArrayInputStream inputStream;
	public String execute() throws Exception{
//		 在内存中创建图象
		int width=85, height=20;
		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//		 获取图形上下文
		Graphics g = image.getGraphics();
//		生成随机类
		Random random = new Random();
//		 设定背景色
		g.setColor(getRandColor(200,250));
		g.fillRect(0, 0, width, height);
//		设定字体
		g.setFont(new Font("Times New Roman",Font.PLAIN,18));
//		 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
		g.setColor(getRandColor(160,200));
		for (int i=0;i<155;i++)
		{
		 int x = random.nextInt(width);
		 int y = random.nextInt(height);
		        int xl = random.nextInt(12);
		        int yl = random.nextInt(12);
		 g.drawLine(x,y,x+xl,y+yl);
		}
//		 取随机产生的认证码(6位数字)
		String sRand="";
		for (int i=0;i<6;i++){
		    String rand=String.valueOf(random.nextInt(10));
		    sRand+=rand;
		    // 将认证码显示到图象中
		    g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
//		调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
		    g.drawString(rand,13*i+6,16);
		}
//		 将认证码存入SESSION
		ActionContext.getContext().getSession().put("rand",sRand);
//		 图象生效
		g.dispose();
		ByteArrayOutputStream output = new ByteArrayOutputStream();
        ImageOutputStream imageOut = ImageIO.createImageOutputStream(output);
        ImageIO.write(image, "JPEG", imageOut);
        imageOut.close();
        ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray());
        this.setInputStream(input);
		return SUCCESS;
	}
	/*
	 * 给定范围获得随机颜色
	 */
	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);
   }
	public void setInputStream(ByteArrayInputStream inputStream) {
		this.inputStream = inputStream;
	}
	public ByteArrayInputStream getInputStream() {
		return inputStream;
	}

}

 2.配置action,将上述action返回的逻辑结果设置为文件流类型。

<action name="rand" class="test.RandomAction">
      <result type="stream">
               <param name="contentType">image/jpeg</param>
               <param name="inputName">inputStream</param>
        </result>
 </action>

 3.写一个测试的html页面,使其请求上面的action,得到返回的图片结果。

 <script type="text/javascript">
    function changeValidateCode(obj) {
           //获取当前的时间作为参数,无具体意义
        var timenow = new Date().getTime();
           //每次请求需要一个不同的参数,否则可能会返回同样的验证码
        //这和浏览器的缓存机制有关系,也可以把页面设置为不缓存,这样就不用这个参数了。
        obj.src="rand.action?d="+timenow;
    }
</script>

<img src="rand.action" onclick="changeValidateCode(this)"/>

 

 现在可以看一下运行结果,点击图片可以改变验证码。如下图所示(当然,下面的图是不可以点的,是让你点自己运行后的程序)

  • 大小: 1.4 KB
分享到:
评论
17 楼 distiny 2013-04-16  
你有没想过你这个验证码每次登陆都是读缓存的..
所以建议:
<%
long time=new Date().getTime();
%>

<img src="rand.action?d=<%=time  %>" onclick="changeValidateCode(this)"/>点击我更换图片<br>

这样就搞定!!
16 楼 rogerrliao 2012-05-22  
兄弟,谢谢你了,很有用,帮了我的大忙,呵呵

不过RandomNumUtil有两个小地方需要做点改动,不然验证会失败

第3行 private String str;  这里的要初始化 str = "" 不然生成的验证码前面有个null,验证的时候会失败

第59行 this.str=rand;应该改成 this.str+=rand; 这个之前已经有哥们讲过了


总之,还是要谢谢你啊

15 楼 edwardjj1234 2012-05-02  
博主,你有一个地方错了,就是在RandomNumUtil的第59行应该是this.yzm=sRand;而不是rand。。。
14 楼 l658775 2012-03-29  
Thanks
13 楼 Apples 2012-02-12  
谢谢,学到了
12 楼 youfang5211314 2011-09-28  
貌似有错啊。
<img src="rand.shtml" onclick="changeValidateCode(this)"/> 
<s:property value="%{#session.random}"/>
结果得到的是null513431,前面不知道那里多出来的null,郁闷了。
11 楼 lxhdj 2010-08-23  
博主你好。我也用stream结果类型做了验证码,action算法、各个xml配置也都和你一样,但是我发现在IE下面验证码不显示,是红叉呢。Firefox、Chrome、Opera、Safari都正常。很奇怪呢...请问你有遇到么?
10 楼 cyp5913 2010-08-17  
在页面上的验证码 怎样传到后台去验证的呀??
9 楼 yangyixiao2009 2010-03-31  
好帖,谢谢楼主的分享。
8 楼 黑色郁金香 2009-12-23  
很不错的实例,收藏,感谢

不过RandomNumUtil里的init()方法中的
for (int i=0;i<6;i++){  
53.            String rand=String.valueOf(random.nextInt(10));  
54.            sRand+=rand;  
55.            // 将认证码显示到图象中  
56.            g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));  
57.            //      调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成  
58.            g.drawString(rand,13*i+6,16);  
59.            this.str=rand;/*   赋值验证码   */ 
60.        }  

this.str=rand;应该改成 this.str+=rand; 不然取得的数字只是最后一位


效果很不错 感谢
7 楼 mxl19860914 2008-12-16  
完美解决~~~服务真到位,以后还来你这来取经哈,呵呵!
6 楼 tianmingqi 2008-12-16  
mxl19860914 写道



Java代码

String&nbsp;str2=(String)(ActionContext.getContext().getSession().get("random"));&nbsp;&nbsp;String str2=(String)(ActionContext.getContext().getSession().get("random"));这里的str2是空值,你看看你的程序是吗?把你这个发我邮箱好吗? 我的邮箱:278738319@qq.com

你好,到你的邮箱看看吧,已经回复你了,错误原因在RandomNumUtil类:
....................
String sRand="";
		for (int i=0;i<6;i++){
		    String rand=String.valueOf(random.nextInt(10));
		    sRand+=rand;
		    // 将认证码显示到图象中
		    g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
		    //		调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
		    g.drawString(rand,13*i+6,16);
		}
		this.str=sRand;/*赋值验证码*/
		//图象生效
		g.dispose();
.............................
5 楼 mxl19860914 2008-12-16  
String str2=(String)(ActionContext.getContext().getSession().get("random"));


这里的str2是空值,你看看你的程序是吗?把你这个发我邮箱好吗?

我的邮箱:278738319@qq.com
4 楼 leilei527 2008-12-16  
哥们,我写了下还是不行,把你程序发给我看看吧……谢谢啦
3 楼 leilei527 2008-12-16  
呵呵,谢谢你了……
2 楼 tianmingqi 2008-12-15  
leilei527 写道

哥们~~~~ 实现验证 验证码的action也写出来吧…… 对了还有个问题:如果想让验证码里是:数字 和 字母的组合应该怎么修改呢?

上述的action只是为了方便才把所有东西都在action里实现了,实际上我在项目中使用的是一个辅助类RandomNumUtil,通过它的对象即可以取得图片,又可以取得图片上的字符串,此类定义如下:
public class RandomNumUtil {
	private ByteArrayInputStream image;//图像
	private String str;//验证码
	
	private RandomNumUtil(){
		init();//初始化属性
	}
	/*
	 * 取得RandomNumUtil实例
	 */
	public static RandomNumUtil Instance(){
		return new RandomNumUtil();
	}
	/*
	 * 取得验证码图片
	 */
	public ByteArrayInputStream getImage(){
		return this.image;
	}
	/*
	 * 取得图片的验证码
	 */
	public String getString(){
		return this.str;
	}
	
	private void init() {
		//		 在内存中创建图象
		int width=85, height=20;
		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		//		 获取图形上下文
		Graphics g = image.getGraphics();
		//		生成随机类
		Random random = new Random();
		//		 设定背景色
		g.setColor(getRandColor(200,250));
		g.fillRect(0, 0, width, height);
		//		设定字体
		g.setFont(new Font("Times New Roman",Font.PLAIN,18));
		//		 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
		g.setColor(getRandColor(160,200));
		for (int i=0;i<155;i++)
		{
		 int x = random.nextInt(width);
		 int y = random.nextInt(height);
		        int xl = random.nextInt(12);
		        int yl = random.nextInt(12);
		 g.drawLine(x,y,x+xl,y+yl);
		}
		//		 取随机产生的认证码(6位数字)
		String sRand="";
		for (int i=0;i<6;i++){
		    String rand=String.valueOf(random.nextInt(10));
		    sRand+=rand;
		    // 将认证码显示到图象中
		    g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
		    //		调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
		    g.drawString(rand,13*i+6,16);
		    this.str=rand;/*   赋值验证码   */
		}
		//		 图象生效
		g.dispose();
		ByteArrayInputStream input=null;
		ByteArrayOutputStream output = new ByteArrayOutputStream();
		try{
			ImageOutputStream imageOut = ImageIO.createImageOutputStream(output);
	        ImageIO.write(image, "JPEG", imageOut);
	        imageOut.close();
	        input = new ByteArrayInputStream(output.toByteArray());
		}catch(Exception e){
			System.out.println("验证码图片产生出现错误:"+e.toString());
		}
        
        this.image=input;/*  赋值图像  */
	}
	/*
	 * 给定范围获得随机颜色
	 */
	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);
   }

}


然后在action中如下使用此辅助类,action代码如下:
public class RandomAction extends ActionSupport{
	private ByteArrayInputStream inputStream;
	public String execute() throws Exception{
		RandomNumUtil rdnu=RandomNumUtil.Instance();
		this.setInputStream(rdnu.getImage());//取得带有随机字符串的图片
		ActionContext.getContext().getSession().put("random", rdnu.getString());//取得随机字符串放入HttpSession
		return SUCCESS;
	}
	public void setInputStream(ByteArrayInputStream inputStream) {
		this.inputStream = inputStream;
	}
	public ByteArrayInputStream getInputStream() {
		return inputStream;
	}


上述action代码不但有了图像,而且有了这个图像上的字符串对象,并且这个字符串对象保存在了session里。这样以后就可以从session中取出这个字符串来与客户输入的图片验证码来对照了。比如这位大哥所说的验证 验证码的action就可以这样来写:

package test;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

public class CheckAction extends ActionSupport{
	private String str;//客户输入的图片验证码
	
	public String execute(){
		String str2=(String)(ActionContext.getContext().getSession().get("random"));//取得session保存中的字符串
		//下面就是将session中保存验证码字符串与客户输入的验证码字符串对比了
		if(str2.equals(this.getStr())){
			return SUCCESS;
		}else{
			return LOGIN;
		}
	}
	public String getStr() {
		return str;
	}

	public void setStr(String str) {
		this.str = str;
	}

}

这样总可以了吧老兄?基本思路就是先将产生的验证码字符串保存在session里,然后再从session中取出来与客户输入验证码的对比。至于怎么产数字与字母的组合图片验证码,老兄想想如何产生随机字母。。。。。。。?不多说了,自己动脑吧!
1 楼 leilei527 2008-12-15  
哥们~~~~

实现验证 验证码的action也写出来吧……

对了还有个问题:如果想让验证码里是:数字 和 字母的组合应该怎么修改呢?

相关推荐

    Struts2-登录验证码

    完整的Struts2框架,联系oracle数据库实现登录验证 验证码功能:点击图片切换验证码,验证码错误提示 登录成功后变量session中的list集合 内含备注

    java动态验证码Struts2集成实现

    java动态验证码Struts2集成实现

    struts2验证码完整实例

    1、页面加载后,想后台发出生产验证码图片的请求,并在前台显示验证码图片,同时将验证码上的数字 通过ActionContext.getContext().getSession().put("random", randomNum.getRandomCode())将数字存放到session当中 2...

    struts2下实现了图片验证码

    想自己写一个验证码吗?其实不用这么麻烦,网上有很多这样的。这里的代码是纯数字的验证码,从页面到配置实现已经详细的解说了,只要粘贴复制就可以了

    基于Exjs6+Struts2拖动(滑动)图片验证码的实现

    用ExtJs6+strust2重新改写的拖动图片验证码的实现方法,基于网络上的Jquery版修改,直接导入myeclipse工程即可。jar包太大,不在压缩包中,需要的同学请参考/webroot/下的“所需jar包列表.jpg”,自己从网络下载jar...

    STRUTS2个人通讯录管理系统

    STRUTS2个人通讯录管理系统实现登陆带验证码分页上传图片mysql数据可

    SSH框架 Struts+Spring+Hibernate+Ajax+功能齐全(验证码+二进制文件图片读写数据库)的网站.zip

    SSH框架 Struts+Spring+Hibernate+Ajax+功能齐全(验证码+二进制文件图片读写数据库)的网站.zip

    达内Struts2.0学习之当当网系统学习案例

    Struts 2.0技术综合应用,包括上传图片功能,明文加密算法SHA-1和MD5,上传用户头像,根据action随机生成验证码,用链接实现数据的分页处理,以及拦截器和Logger日志框架的引入,总之相当强大,学习Struts 2.0,把这...

    登录 单点登录 带验证码登录

    这是一个简单而完整的登录实例,实现单点登录效果,java自动生成图片验证码,访问拦截,没登录时不可以访问会员页面。是一个完整的实例,struts构建,内有jar包。

    FreeMarke实例代码

    由FreeMarker生成页面,通过模板显示准备的数据 FreeMarker...FreeMarker同样可以应用于非Web应用程序环境 FreeMarker更适合作为Model2框架(如Struts)的视图组件,你也可以在模板中使用JSP标记库 FreeMarker是免费的

    struts2.1.8+JPA3.0(hibernate实现)+spring2.5+extjs3.2中型BBS项目

    支持上传图片和文件,文件作为附件可以下载,图片可直接在JSP页面中显示 支持回帖,并在主楼中显示 答辩用PPT 选做部分: 帖子搜索 用户查找 管理员对帖子加精、置顶 根据浏览量,自动在首页生成热门帖子列表...

    搭建SSH框架的代码

    8.有全文检索工具类包含索引的创建、查询等,自动分页Bean,Excel读取/导出等功能、汉字转拼音,MD5加密,加密解密,图片转字符、字符转图片,IP检查,拦截器权限拦截,Struts2Utils类,Spring3Utils类,轻松搞定...

    百度地图毕业设计源码-FutureStudio:这是在Struts2、Hibernate3、Spring3上构建的J2ee项目

    提供一套图片验证码,邮箱验证码的功能(图片验证码使用百度服务,本地版本计划中,暂未实现,) (已废弃)06 log 这个工程的原本目标是为系统的所有日志提供一个方案,方便于以后对日志的输出,进

    当当网全套源码(附带邮箱验证功能)

    Struts2,JDBC(连接池),jQuery,Ajax 2)设计思想 MVC和分层设计思想 a.显示层:JSP组件(jQuery,Ajax) b.控制层:Struts2控制器组件、Action组件 c.业务层:Bean组件 d.数据访问层:DAO组件(JDBC) 4.数据库...

    java开源包2

    Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...

    java开源包5

    Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...

    java开源包3

    Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...

    java开源包4

    Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...

    java开源包1

    Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...

    java开源包11

    Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (&lt;jcaptcha:image label="Type the text "/&gt; ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码图片。 Java 命令行解析...

Global site tag (gtag.js) - Google Analytics