Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 339|回复: 0

[jsf学习]在web应用中部署验证码(jsp,jsf两种方式)

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-10 01:50:51 | 显示全部楼层 |阅读模式
    在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=GBK" language="java"%>

    <%@ taglib uri="http://jakarta.apache.org/taglibs/image-1.0" prefix="img" %>
    <html>
    <head>
    <title>ImageTagexamples</title>
    <metahttp-equiv="Content-Type"content="text/html;charset=iso-8859-1">
    </head>
    <body>

    <%
    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/auth.jpg" 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="TimesNewRoman" 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="TimesNewRoman" 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(0, 0, width, height);
             // draw the border
             g.setColor(Color.black);
             g.drawRect(0, 0, 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, 0, 0);
             } // 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 + 6, 16);
             }
             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中实现了自己的验证码部署^_^

      
      
       
       

         
       

         
       
      



    源码下载:http://file.javaxxz.com/2014/10/10/015051250.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-6-16 08:38 , Processed in 0.586824 second(s), 38 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表