zoukankan      html  css  js  c++  java
  • 使用纯Servlet实现验证码

    (1)在web.xml配置:
    view plaincopy to clipboardprint?
    <servlet>     
        <servlet-name>image</servlet-name>     
        <servlet-class>org.test.web.AuthImage</servlet-class>     
    </servlet>     
        
    <servlet-mapping>     
        <servlet-name>image</servlet-name>     
     <url-pattern>/authImage</url-pattern>     
    </servlet-mapping>   
    <servlet>  
        <servlet-name>image</servlet-name>  
        <servlet-class>org.test.web.AuthImage</servlet-class>  
    </servlet>  
     
    <servlet-mapping>  
        <servlet-name>image</servlet-name>  
     <url-pattern>/authImage</url-pattern>  
    </servlet-mapping>  

    (2)servlet源码

    view plaincopy to clipboardprint?
    public class AuthImage extends HttpServlet     
    {     
        
        private static final String CONTENT_TYPE = "text/html; charset=gb2312";     
        //设置字母的大小,大小     
        private Font mFont = new Font("Times New Roman", Font.PLAIN, 17);     
        public void init() throws ServletException     
        {     
            super.init();     
        }     
        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 service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException     
        {     
            response.setHeader("Pragma","No-cache");     
            response.setHeader("Cache-Control","no-cache");     
            response.setDateHeader("Expires", 0);     
            //表明生成的响应是图片     
            response.setContentType("image/jpeg");     
                 
            int width=100, height=18;     
            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(1, 1, width-1, height-1);     
            g.setColor(new Color(102,102,102));     
            g.drawRect(0, 0, width-1, height-1);     
            g.setFont(mFont);     
        
            g.setColor(getRandColor(160,200));     
        
            //画随机线     
            for (int i=0;i<155;i++)     
            {     
                int x = random.nextInt(width - 1);     
                int y = random.nextInt(height - 1);     
                int xl = random.nextInt(6) + 1;     
                int yl = random.nextInt(12) + 1;     
                g.drawLine(x,y,x + xl,y + yl);     
            }     
        
            //从另一方向画随机线     
            for (int i = 0;i < 70;i++)     
            {     
                int x = random.nextInt(width - 1);     
                int y = random.nextInt(height - 1);     
                int xl = random.nextInt(12) + 1;     
                int yl = random.nextInt(6) + 1;     
                g.drawLine(x,y,x - xl,y - yl);     
            }     
        
            //生成随机数,并将随机数字转换为字母     
            String sRand="";     
            for (int i=0;i<6;i++)     
            {     
                int itmp = random.nextInt(26) + 65;     
                char ctmp = (char)itmp;     
                sRand += String.valueOf(ctmp);     
                g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));     
                g.drawString(String.valueOf(ctmp),15*i+10,16);     
            }     
        
            HttpSession session = request.getSession(true);     
            session.setAttribute("rand",sRand);     
            g.dispose();     
            ImageIO.write(image, "JPEG", response.getOutputStream());     
        }     
        public void destroy()     
        {     
        }     
    }   
    public class AuthImage extends HttpServlet  
    {  
     
        private static final String CONTENT_TYPE = "text/html; charset=gb2312";  
        //设置字母的大小,大小  
        private Font mFont = new Font("Times New Roman", Font.PLAIN, 17);  
        public void init() throws ServletException  
        {  
            super.init();  
        }  
        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 service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException  
        {  
            response.setHeader("Pragma","No-cache");  
            response.setHeader("Cache-Control","no-cache");  
            response.setDateHeader("Expires", 0);  
            //表明生成的响应是图片  
            response.setContentType("image/jpeg");  
              
            int width=100, height=18;  
            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(1, 1, width-1, height-1);  
            g.setColor(new Color(102,102,102));  
            g.drawRect(0, 0, width-1, height-1);  
            g.setFont(mFont);  
     
            g.setColor(getRandColor(160,200));  
     
            //画随机线  
            for (int i=0;i<155;i++)  
            {  
                int x = random.nextInt(width - 1);  
                int y = random.nextInt(height - 1);  
                int xl = random.nextInt(6) + 1;  
                int yl = random.nextInt(12) + 1;  
                g.drawLine(x,y,x + xl,y + yl);  
            }  
     
            //从另一方向画随机线  
            for (int i = 0;i < 70;i++)  
            {  
                int x = random.nextInt(width - 1);  
                int y = random.nextInt(height - 1);  
                int xl = random.nextInt(12) + 1;  
                int yl = random.nextInt(6) + 1;  
                g.drawLine(x,y,x - xl,y - yl);  
            }  
     
            //生成随机数,并将随机数字转换为字母  
            String sRand="";  
            for (int i=0;i<6;i++)  
            {  
                int itmp = random.nextInt(26) + 65;  
                char ctmp = (char)itmp;  
                sRand += String.valueOf(ctmp);  
                g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));  
                g.drawString(String.valueOf(ctmp),15*i+10,16);  
            }  
     
            HttpSession session = request.getSession(true);  
            session.setAttribute("rand",sRand);  
            g.dispose();  
            ImageIO.write(image, "JPEG", response.getOutputStream());  
        }  
        public void destroy()  
        {  
        }  
    }  

    (3)页面显示

    view plaincopy to clipboardprint?
    <img src="authImage"/>  
    <img src="authImage"/> 

    二、使用纯jsp实现验证码

    view plaincopy to clipboardprint?
    <%@ page language="java" import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*"   
         contentType="image/jpeg" pageEncoding="UTF-8"%>  
     
     
    <%  //设置页面不缓存  
       response.setHeader("Pragma","No-cache");  
       response.setHeader("Cahce-Control","no-cache");  
       response.setDateHeader("Expires",0);  
       //在内存中创建图片  
       int width=60,height=20;  
       BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);  
       //获取图形上下文  
       Graphics g= image.getGraphics();  
       //生成随机类  
       Random random= new Random();  
       //设置背景颜色  
       g.setColor(new Color(160,200,100));  
       g.fillRect(0,0,width,height);  
       //设置字体  
       g.setFont(new Font("Times New Roman",Font.PLAIN,18));  
       //随机产生50条干扰线,使图形中的验证码不易被其他的程序探测到  
        g.setColor(new Color(160,200,200));  
       for(int i=0;i<50;i++)  
       {  
         int x=random.nextInt(width);  
         int y=random.nextInt(height);  
         int x1=random.nextInt(width);  
         int y1=random.nextInt(height);  
         g.drawLine(x,y,x+x1,y+y1);  
       }  
       //随机产生验证码(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.setAttribute("rand",sRand);  //////将产生的验证码存储到sesson中  
       g.dispose();  
       ImageIO.write(image,"JPEG",response.getOutputStream());  
       out.clear(); //***********  
       out=pageContext.pushBody();//**********  
     %> 
    <%@ page language="java" import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*"
         contentType="image/jpeg" pageEncoding="UTF-8"%>


    <%  //设置页面不缓存
       response.setHeader("Pragma","No-cache");
       response.setHeader("Cahce-Control","no-cache");
       response.setDateHeader("Expires",0);
       //在内存中创建图片
       int width=60,height=20;
       BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
       //获取图形上下文
       Graphics g= image.getGraphics();
       //生成随机类
       Random random= new Random();
       //设置背景颜色
       g.setColor(new Color(160,200,100));
       g.fillRect(0,0,width,height);
       //设置字体
       g.setFont(new Font("Times New Roman",Font.PLAIN,18));
       //随机产生50条干扰线,使图形中的验证码不易被其他的程序探测到
        g.setColor(new Color(160,200,200));
       for(int i=0;i<50;i++)
       {
         int x=random.nextInt(width);
         int y=random.nextInt(height);
         int x1=random.nextInt(width);
         int y1=random.nextInt(height);
         g.drawLine(x,y,x+x1,y+y1);
       }
       //随机产生验证码(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.setAttribute("rand",sRand);  //////将产生的验证码存储到sesson中
       g.dispose();
       ImageIO.write(image,"JPEG",response.getOutputStream());
       out.clear(); //***********
       out=pageContext.pushBody();//**********
     %>
     

    三、使用Struts2来实现验证码

    (1)定义一个生成验证码的工具类

    view plaincopy to clipboardprint?
    package com.cn.hospital.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.util.Random;     
    import javax.imageio.ImageIO;     
    import javax.imageio.stream.ImageOutputStream;     
     
    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=sRand;      
            
        //图象生效      
        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);      
        }     

    package com.cn.hospital.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.util.Random;  
    import javax.imageio.ImageIO;  
    import javax.imageio.stream.ImageOutputStream;  

    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=sRand;   
      
     //图象生效   
     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);   
     }  
    }
     

    (2)定义一个验证码输出的action

    view plaincopy to clipboardprint?
    package com.cn.hospital.action;  
     
    import java.io.ByteArrayInputStream;  
    import java.io.ByteArrayOutputStream;  
     
    import org.springframework.context.annotation.Scope;  
    import org.springframework.stereotype.Controller;  
     
    import com.cn.hospital.util.RandomCharUtil;  
    import com.cn.hospital.util.RandomNumUtil;  
    import com.opensymphony.xwork2.ActionContext;  
    import com.opensymphony.xwork2.ActionSupport;  
     
    @Controller("utilAction")  
    @Scope("prototype")  
    public class UtilAction extends ActionSupport{  
          
        private static final long serialVersionUID = -7193209177116825032L;  
        private ByteArrayInputStream inputStream;   
          
        private int width;     
        private int height;     
        private int fontSize;     
        private int codeLength;   
        private int disturbType;  
          
        public String validNumGenerate() 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;      
        }  
          
     

    package com.cn.hospital.action;

    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;

    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Controller;

    import com.cn.hospital.util.RandomCharUtil;
    import com.cn.hospital.util.RandomNumUtil;
    import com.opensymphony.xwork2.ActionContext;
    import com.opensymphony.xwork2.ActionSupport;

    @Controller("utilAction")
    @Scope("prototype")
    public class UtilAction extends ActionSupport{
     
     private static final long serialVersionUID = -7193209177116825032L;
     private ByteArrayInputStream inputStream;
     
     private int width;  
        private int height;  
        private int fontSize;  
        private int codeLength;
        private int disturbType;
     
     public String validNumGenerate() 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;   
     }
     

    }
     

    (3)struts.xml配置

    view plaincopy to clipboardprint?
    <!-- 产生随机验证码 -->  
            <action name="randNum" class="utilAction" method="validNumGenerate">        
               <result name="success" type="stream">        
                    <param name="contentType">image/jpeg</param>        
                    <param name="inputName">inputStream</param>        
               </result>     
            </action>  
    <!-- 产生随机验证码 -->
      <action name="randNum" class="utilAction" method="validNumGenerate">     
            <result name="success" type="stream">     
                 <param name="contentType">image/jpeg</param>     
                 <param name="inputName">inputStream</param>     
            </result>  
         </action> 

    四、小结

        对于java的web技术,归根究底还是在服务器端执行的servlet.从上面的三种不同实现中,我们很容易察觉到他们存在一个共同点,那就是返回浏览器端的contentType。

        servlet:使用response.setContentType(" ");方法来实现

        jsp:在<@ page contentType=" ">中来实现

        struts2:通过配置<param name="contentType"> </param>来实现

  • 相关阅读:
    Office 2003正版验证破解方法
    QQ邮箱 503 : HTTP Error 503 服务暂时不可用,请刷新重试
    再加几个MQL4 中的字符串处理函数
    C 处理可变参数函数 (二)
    Memcache 中实现消息队列
    提供MQL4 中比较实用的两个字符串处理函数
    在freebsd 上编译 pango with cairo
    C语言小技巧(1) 实现可变参数
    PHP 中的递归效率
    windows 下php 扩展 的好 资源
  • 原文地址:https://www.cnblogs.com/rongxiang/p/2351294.html
Copyright © 2011-2022 走看看