dyerac  
dyerac In Java
公告

日历
<2006年8月>
303112345
6789101112
13141516171819
20212223242526
272829303112
3456789
统计
  • 随笔 - 36
  • 文章 - 10
  • 评论 - 94
  • 引用 - 0

导航

常用链接

留言簿(5)

随笔分类(49)

随笔档案(36)

文章分类(11)

文章档案(10)

相册

dyerac

搜索

  •  

积分与排名

  • 积分 - 77958
  • 排名 - 707

最新随笔

最新评论

阅读排行榜

评论排行榜

 

     在web系统中,验证码的应用基本上随处可见.验证码可以防止他人恶意攻击和垃圾注册,可以说已成了web开发中必不可少的环节.遗憾的是,验证码在jsp,jsf的组件库, 至少是一些标准的组件库中并没有出现.本文分别介绍如何在jsp和jsf中使用验证码和我的一些小经验,呵呵.
     在jsp中,我们使用apache的taglibs-image(http://jakarta.apache.org/taglibs/sandbox/doc/image-doc/intro.html),可以简便的配置自己的验证码.而由于在jsf中,无法和其他jsp标签库混用(至少不能和上述标签库混用),我们则用Java2D自己绘制验证码图.
 

1. 在jsp中使用taglibs-image部署验证码
    taglibs-image可以通过标签自动将一段文字和背景图片生成新的图片,文字的布局,颜色,字体等等都可以自我定制,因此拿来做验证码是非常的简单
   

<% @ page contentType = " text/html; charset=iso-8859-1 "  language = " java "   import = " java.sql.* "  errorPage = ""   %>
<% @ taglib uri = " http://jakarta.apache.org/taglibs/image-1.0 "  prefix = " img "   %>

< html >
< head >
< title > Image Tag examples </ title >
< meta http - equiv = " Content-Type "  content = " text/html; charset=iso-8859-1 " >
</ head >

< body >
td
 
<%
  
int  num  =  ( int ) java.lang.Math.round(java.lang.Math.random()  *   8999 );
  String sRand 
=   ""   +  ( 1000   + num);
  session.setAttribute(
" userInfo.authcode " ,sRand);
 
%>
< img:image src = " /images/code.gif "  refresh = " true " >
  
< img:text text = " <%=sRand.substring(0,1)%> "  x = " 18% "  
        y
= " 25% "  
        font
= " Arial "  
        bold
= " true "  
        size
= " 16 "  
        
/>
  
< img:text text = " <%=sRand.substring(1,2)%> "  x = " 36% "  
        y
= " 15% "  
        font
= " Times New Roman "  
        bold
= " true "  
        size
= " 20 "  
        
/>
  
< img:text text = " <%=sRand.substring(2,3)%> "  x = " 60% "  
        y
= " 20% "  
        font
= " Arial "  
        bold
= " true "  
        size
= " 18 "  
        
/>
  
< img:text text = " <%=sRand.substring(3,4)%> "  x = " 77% "  
        y
= " 30% "  
        font
= " Times New Roman "  
        bold
= " true "  
        size
= " 14 "  
        
/>
</ img:image >
</ body >
</ html >

   其中最开始百分号内的java代码是为了生成验证码,然后保存在session中.同时验证码和背景图片生成新的验证图.用户根据此图输入验证码.在服务器方,只用把用户提交表单中的验证码内容取出和session中保存的验证码对比,就可以判断正确性咯
             

2.JSF
   jsf中无法使用上述标签(会无法渲染出来), 因此,我们自己实现一个生成验证图的类,再通过jsf的<h:graphicImage>标签得以显示.
  生成验证码的java类如下:
package org.myibm.beans;

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

import javax.imageio.ImageIO;

/**
 * 用来自动生成验证图和验证码,验证图是背景图加上干扰点加上验证码
 * 
 * 
@author td
 * 
 
*/

public final class CodeImageGenerator {
    
private final static int DEF_WIDTH = 60;

    
private final static int DEF_HEIGHT = 20;

    
private final static String BASE_PATH = "validate-images";

    
/**
     * 验证码
     
*/

    
private String code = "";

    
/**
     * 验证图的地址
     
*/

    
private String path;

    
private int width;

    
private int height;

    
private BufferedImage image;

    
/**
     * 验证图对应的File对象
     
*/

    
private File target;

    
public CodeImageGenerator() {
        
this(DEF_WIDTH, DEF_HEIGHT);
    }


    
public CodeImageGenerator(int width, int height) {
        
this.width = width;
        
this.height = height;
        generateCodeImage();
    }


    
/**
     * 生成验证码和验证图
     *
     
*/

    
private void generateCodeImage() {
        
// create the image
        image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics g 
= image.getGraphics();
        
// set the background color
        g.setColor(new Color(0xDCDCDC));
        g.fillRect(
00, width, height);
        
// draw the border
        g.setColor(Color.black);
        g.drawRect(
00, width - 1, height - 1);
        
// set the font
        g.setFont(new Font("Times New Roman", Font.PLAIN, 18));
        
// create a random instance to generate the codes
        Random random = new Random();
        
// make some confusion
        for (int i = 0; i < 50; i++{
            
int x = random.nextInt(width);
            
int y = random.nextInt(height);
            g.drawOval(x, y, 
00);
        }
 // generate a random code
        for (int i = 0; i < 4; i++{
            String rand 
= String.valueOf(random.nextInt(10));
            code 
+= rand;
            g.drawString(rand, 
13 * i + 616);
        }

        g.dispose();
        
try {
            File dir 
= new File("K:/Tomcat 5.5/webapps/nirvana/validate-images");
            String s 
= new Double(Math.random() * 995596390219L).toString();
            File imgFile 
= new File(dir, s + ".jpeg");
            
if (!imgFile.exists())
                imgFile.createNewFile();
            target 
= imgFile;
            ImageIO.write(image, 
"JPEG", imgFile);
            path 
= "/" + BASE_PATH + "/" + s + ".jpeg";
            System.err.println(path);
        }
 catch (IOException e) {
            
// TODO Auto-generated catch block
            e.printStackTrace();
        }

    }


    
public BufferedImage getImage() {
        
return image;
    }


    
public String getCode() {
        
if (code == null)
            code 
= "";
        
return code;
    }


    
public static void main(String[] args) throws Exception {
        
// File imgFile = new File("codeImage.jpeg");
        
// CodeImageGenerator cig = new CodeImageGenerator();
        
// ImageIO.write(cig.getImage(), "JPEG", imgFile);
    }


    
public String getPath() {
        
return path;
    }


    
public void setPath(String path) {
        
this.path = path;
    }


    
/**
     * 当这个对象被回收时,同时销毁其对应的验证图
     
*/

    @Override
    
protected void finalize() throws Throwable {
        
// TODO Auto-generated method stub
        
// System.err.println("finalize");
        if (target.exists())
            target.delete();
        
super.finalize();
    }


    
public File getTarget() {
        
return target;
    }


    
public void setTarget(File target) {
        
this.target = target;
    }

}


要说明几点的事,这个类会把生成的验证图放在制定文件夹下,未免得文件越来越多,应该当验证图不再使用时将之删除.所以此类重写了Object的finalize()方法,当此类被垃圾回收器回收时,同时也删除其对应的验证图.
这样,就可以利用java的垃圾回收器轻松为我们删除不用的文件.

另外,在页面对应的managed-bean中,我们还要添加如何得到验证码和验证图的方法

private CodeImageGenerator validator;
    
    
private String validate_code;
    
    
public CodeImageGenerator getValidator() {
        
if(validator!=null){
            validator.getTarget().delete();
            validator
=null;
        }

        validator
=new CodeImageGenerator();
        System.out.println(validator.getCode());
        
return validator;
    }


    
public void setValidator(CodeImageGenerator validator) {
        
this.validator = validator;
    }

其中validate-code对应用户输入的验证码信息
因为每次刷新页面都需要得到不同的验证码,所以在getValidator()方法时,每次需要返回一个新的CodeImageGenerator.同时,你可能等不及垃圾回收器帮你删除文件,因此,可以在这里同时删除老的验证图.

另外,在注册时我们还需要做一下判断:
public String register() {
        
// System.out.println("haha");
        if(!validator.getCode().equals(validate_code)){
            FacesMessage message 
= new FacesMessage(
                    FacesMessage.SEVERITY_ERROR, 
"验证码错误",
                    
"验证码错误");
            FacesContext.getCurrentInstance().addMessage(
null, message);
            FacesContext fcg 
= FacesContext.getCurrentInstance();
            ((LoginBean) fcg.getApplication().getVariableResolver()
                    .resolveVariable(fcg, 
"loginBean")).setReg(true);
            System.out.println(validator.getCode());
            System.out.println(validate_code);
            
return null;
        }

..
}

最后,我们需要在页面中添加对应的标签


                        <h:outputText value="验证码(*):" styleClass="label"></h:outputText>
                        
<h:message for="vcode" styleClass="error"></h:message>

                        
<h:inputText id="vcode" required="true" value="#{myPageBean.validate_code}"></h:inputText>
                        
<h:graphicImage value="#{myPageBean.validator.path}"></h:graphicImage>

这样, 我们就在jsf中实现了自己的验证码部署^_^

posted on 2006-08-03 12:52 dyerac in java... 阅读(2727) 评论(1)  编辑  收藏 所属分类: 原创文章JavaEE
评论:
  • # re: 在web应用中部署你自己的验证码(jsp,jsf两种方式)[未登录]  ken Posted @ 2009-07-04 07:48
    页面用的那个标签没有办法显示 图片,现实的是红色叉叉

    请教如何解决?

    niceken520@gmail.com  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 
 
Copyright © dyerac in java... Powered by: 博客园 模板提供:沪江博客