带字符旋转的彩色 java 验证码

/*一共三个部分

*  1. java代码

*  2. servlet配置

*  3. jsp文件

*  分别保存即可

*/

//附效果图

/*

*   验证码 源码  请保存为VerifyCode1.java

*/

 

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

public class VerifyCode1 extends HttpServlet{
    private static VerifyCode1 instance ;
    //private static final VerifyCode1 generator = new VerifyCode1();
    private final String ATTRIBUTE_NAME = "verifycode";
    //验证码长度
    private final int CODE_LENGTH = 4;
 //随机字符串范围
    private final String RAND_RANGE = "abcdefghijklmnopqrstuvwxyz"+
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +"1234567890";
       
    private Random rand = new Random();
    //可选字体
 private String[] FontFamily={"Times New Roman","宋体","黑体","Arial Unicode MS","Lucida Sans"};
 //选转标志,验证码旋转
 private boolean ROTATE_FLAG=true;
 //高度,设置旋转后,高度设为30,否则设置成25,效果好一些
 private int Height = 30;
 
 private final char[] CHARS = RAND_RANGE.toCharArray();
   
    public VerifyCode1(){
        //
    }
   
   
    public static VerifyCode1 getInstance(){
        if(instance == null)
         instance = new VerifyCode1();
        return instance;
    }
    
    /**
     * 生成随机字符串
     * @return 随机字符串
     */
    private String getRandString(){
        StringBuffer vcode = new StringBuffer();
        for (int i = 0; i < CODE_LENGTH; i++)
         vcode.append(CHARS[rand.nextInt(CHARS.length)]);
        return vcode.toString();
    }
   
    /**
     * 生成随机颜色
     * @param ll 产生颜色值下限(lower limit)
     * @param ul 产生颜色值上限(upper limit)
     * @return 生成的随机颜色对象
     */
    private Color getRandColor(int ll, int ul){
        if (ll > 255) ll = 255;
        if (ll < 1) ll = 1;
        if (ul > 255) ul = 255;
        if (ul < 1) ul = 1;
        if (ul == ll) ul = ll + 1;
        int r = rand.nextInt(ul - ll) + ll;
        int g = rand.nextInt(ul - ll) + ll;
        int b = rand.nextInt(ul - ll) + ll;
        Color color = new Color(r,g,b);
        return color;
    }
   
    /**
     * 生成指定字符串的图像数据
     * @param verifyCode 即将被打印的随机字符串
     * @return 生成的图像数据
     * */
    private BufferedImage getImage(String verifyCode){
     int width = CODE_LENGTH * 18 + 20;
        BufferedImage image = new BufferedImage(width, Height, BufferedImage.TYPE_INT_RGB);
       
        //获取图形上下文
        Graphics graphics = image.getGraphics();
        Graphics2D g2 = (Graphics2D) graphics;
        g2.setColor(getRandColor(100,255));
        g2.fillRect(0, 0, width, Height);
  //边框
  //g2.drawRect(0,0,CODE_LENGTH * 18 + 20,Height);
  //5条干扰线
  for(int i=0;i<5;i++){
   g2.setColor(new Color(rand.nextInt(255),rand.nextInt(255),rand.nextInt(255)));
   g2.drawLine(rand.nextInt(width),rand.nextInt(Height),
     rand.nextInt(width),rand.nextInt(Height));
  }
  
  int fontsize;
  int fontstyle = 0;
  double oldrot = 0;
  String vcode = getRandString();
  for (int i=0; i<CODE_LENGTH; i++){
   fontsize = Math.abs(rand.nextInt(24));
            // 18-24 fontsize
            if(fontsize < 12)
             fontsize += 12;
            if(fontsize < 18)
             fontsize += 6;
            fontstyle=rand.nextInt(6) ;
            g2.setFont(new Font(FontFamily[rand.nextInt(5)], fontstyle, fontsize));
            double rot = -0.25 + Math.abs(Math.toRadians(rand.nextInt(25)));
           
            //如果设置选装标志,则旋转文字
            if(ROTATE_FLAG){
             g2.rotate(-oldrot,10,15);
             oldrot = rot;
             g2.rotate(rot,15 * i + 10 , 15);
            }
           
            float stroke = Math.abs(rand.nextFloat()%30);
            g2.setStroke(new BasicStroke(stroke));
            String temp = vcode.substring(i, i+1);
            g2.setColor(new Color(rand.nextInt(255),rand.nextInt(255),rand.nextInt(255)));
            g2.setColor(getRandColor(1,100));
            g2.drawString(temp, 18 * i + 10, 20);
        }
     //图像生效
  g2.dispose();
        return image;
    }
   
    /**
     * 将验证码的图像输出
     * @param request 用户的请求对象
     * @param response 用户的响应对象
     * */
    public void printImage(HttpServletRequest request,
            HttpServletResponse response){
        //将ContentType设为"image/jpeg",让浏览器识别图像格式。
        response.setContentType("image/jpeg");
        //设置页面不缓存
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 2000);
       
        //获得随机验证码
        String verifyCode = this.getRandString();
        //获得验证码的图像数据
        BufferedImage bi = this.getImage(verifyCode);
        //把验证码存入session
        request.getSession().setAttribute(ATTRIBUTE_NAME, verifyCode);
        try{
            //获得Servlet输出流
            ServletOutputStream outStream = response.getOutputStream();
            //创建可用来将图像数据编码为JPEG数据流的编码器
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(outStream);
            //将图像数据进行编码
            encoder.encode(bi);
            //强行将缓冲区的内容输入到页面
            outStream.flush();
            //关闭输出流
            outStream.close();
        }catch(IOException ex){
            ex.printStackTrace();
        }
    }
    public void doGet(HttpServletRequest request,HttpServletResponse response){
     printImage(request,response);
    }

    /**
     * 检查输入的验证码是否正确,若用户输入的验证码与生成的验证码相符则返回true,否则返回false。
     * @param request 用户的请求对象
     * @return 验证结果
     * */
    public boolean check(HttpServletRequest request){
        if (((String)request.getParameter(ATTRIBUTE_NAME))
                .equalsIgnoreCase((String)request.getSession().getAttribute(ATTRIBUTE_NAME))){
            request.getSession().removeAttribute(ATTRIBUTE_NAME);
            return true;
        }
        return false;
    }
}

 

//servlet 配置

<servlet>
 <servlet-name>GetVerCode</servlet-name>
 <servlet-class>VerifyCode1</servlet-class>
 </servlet>
 <servlet-mapping>
  <servlet-name>GetVerCode</servlet-name>
  <url-pattern>/</url-pattern>
 </servlet-mapping>

 

//jsp文件

<%@ page language="java" pageEncoding="utf-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
   
    <title>验证码</title>
  </head>
  <script>
   function changevc(){
  var o = document.getElementById("vercode");
  o.src="GetVerCode?rnd=" + Math.random();
 }
  </script>
  <body>
   <form action="">
     验证码:<input type="text" name="vcode">
     <img src="GetVerCode" id="vercode">
     <a href="javascript:changevc()">看不清</a>
    </form>
  </body>
</html>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值