java图形验证码生成工具类 web页面校验验证码

最近做验证码,参考网上案例,发现有不少问题,特意进行了修改和完善。

验证码生成器:

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.Random; 

/**
 * 验证码生成器
 *
 * @author
 */
public class ValidateCode {
 // 图片的宽度。
 private int width = 160;
 // 图片的高度。
 private int height = 40;
 // 验证码字符个数
 private int codeCount = 5;
 // 验证码干扰线数
 private int lineCount = 150;
 // 验证码
 private String code = null;
 // 验证码图片Buffer
 private BufferedImage buffImg = null; 

 // 验证码范围,去掉0(数字)和O(拼音)容易混淆的(小写的1和L也可以去掉,大写不用了)
 private char[] codeSequence = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
   'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
   'X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; 

 /**
  * 默认构造函数,设置默认参数
  */
 public ValidateCode() {
  this.createCode();
 } 

 /**
  * @param width 图片宽
  * @param height 图片高
  */
 public ValidateCode(int width, int height) {
  this.width = width;
  this.height = height;
  this.createCode();
 } 

 /**
  * @param width  图片宽
  * @param height 图片高
  * @param codeCount 字符个数
  * @param lineCount 干扰线条数
  */
 public ValidateCode(int width, int height, int codeCount, int lineCount) {
  this.width = width;
  this.height = height;
  this.codeCount = codeCount;
  this.lineCount = lineCount;
  this.createCode();
 } 

 public void createCode() {
  int x = 0, fontHeight = 0, codeY = 0;
  int red = 0, green = 0, blue = 0; 

  x = width / (codeCount + 2);//每个字符的宽度(左右各空出一个字符)
  fontHeight = height - 2;//字体的高度
  codeY = height - 4; 

  // 图像buffer
  buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
  Graphics2D g = buffImg.createGraphics();
  // 生成随机数
  Random random = new Random();
  // 将图像填充为白色
  g.setColor(Color.WHITE);
  g.fillRect(0, 0, width, height);
  // 创建字体,可以修改为其它的
  Font font = new Font("Fixedsys", Font.PLAIN, fontHeight);
//  Font font = new Font("Times New Roman", Font.ROMAN_BASELINE, fontHeight);
  g.setFont(font); 

  for (int i = 0; i < lineCount; i++) {
   // 设置随机开始和结束坐标
   int xs = random.nextInt(width);//x坐标开始
   int ys = random.nextInt(height);//y坐标开始
   int xe = xs + random.nextInt(width / 8);//x坐标结束
   int ye = ys + random.nextInt(height / 8);//y坐标结束 

   // 产生随机的颜色值,让输出的每个干扰线的颜色值都将不同。
   red = random.nextInt(255);
   green = random.nextInt(255);
   blue = random.nextInt(255);
   g.setColor(new Color(red, green, blue));
   g.drawLine(xs, ys, xe, ye);
  } 

  // randomCode记录随机产生的验证码
  StringBuffer randomCode = new StringBuffer();
  // 随机产生codeCount个字符的验证码。
  for (int i = 0; i < codeCount; i++) {
   String strRand = String.valueOf(codeSequence[random.nextInt(codeSequence.length)]);
   // 产生随机的颜色值,让输出的每个字符的颜色值都将不同。
   red = random.nextInt(255);
   green = random.nextInt(255);
   blue = random.nextInt(255);
   g.setColor(new Color(red, green, blue));
   g.drawString(strRand, (i + 1) * x, codeY);
   // 将产生的四个随机数组合在一起。
   randomCode.append(strRand);
  }
  // 将四位数字的验证码保存到Session中。
  code = randomCode.toString();
 } 

 public void write(String path) throws IOException {
  OutputStream sos = new FileOutputStream(path);
  this.write(sos);
 } 

 public void write(OutputStream sos) throws IOException {
  ImageIO.write(buffImg, "png", sos);
  sos.close();
 } 

 public BufferedImage getBuffImg() {
  return buffImg;
 } 

 public String getCode() {
  return code;
 } 

 /**
  * 测试函数,默认生成到d盘
  * @param args
  */
 public static void main(String[] args) {
  ValidateCode vCode = new ValidateCode(160,40,5,150);
  try {
   String path="D:/"+new Date().getTime()+".png";
   System.out.println(vCode.getCode()+" >"+path);
   vCode.write(path);
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}

下面是页面JS调用验证码

// 刷新图片
  function changeImg() {
   var imgSrc = $("#imgObj");
   var url = imgSrc.attr("src");
   imgSrc.attr("src", changeUrl(url));
  }
  //为了使每次生成图片不一致,即不让浏览器读缓存,所以需要加上时间戳
  function changeUrl(url) {
   var timestamp = (new Date()).valueOf();
   var index = url.indexOf("?");
   console.log(index);
   if (index > 0) {
    url = url.substring(0, url.indexOf("?"));
   }
   console.log(url);
   if ((url.indexOf("&") > 0)) {
    url = url + "×tamp=" + timestamp;
    console.log(url);
   } else {
    url = url + "?timestamp=" + timestamp;
    console.log(url);
    }
   return url;
  }

下面是controller层输出验证码

/**
 * 响应验证码页面
 * @return
 */
@RequestMapping(value="/validateCode")
public String validateCode(HttpServletRequest request,HttpServletResponse response) throws Exception{
 // 设置响应的类型格式为图片格式
 response.setContentType("image/jpeg");
 //禁止图像缓存。
 response.setHeader("Pragma", "no-cache");
 response.setHeader("Cache-Control", "no-cache");
 response.setDateHeader("Expires", 0); 

 HttpSession session = request.getSession(); 

 ValidateCode vCode = new ValidateCode(120,40,5,100);
 session.setAttribute("code", vCode.getCode());
 vCode.write(response.getOutputStream());
 return null;
}

下面是controller层验证验证码输入是否正确

String code = request.getParameter("code");
HttpSession session = request.getSession();
String sessionCode = (String) session.getAttribute("code");
if (!StringUtils.equalsIgnoreCase(code, sessionCode)) { //忽略验证码大小写
 throw new RuntimeException("验证码对应不上code=" + code + " sessionCode=" + sessionCode);
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java Web项目中实现文件下载功能的实例教程

    需求:实现一个具有文件下载功能的网页,主要下载压缩包和图片 两种实现方法: 一:通过超链接实现下载 在HTML网页中,通过超链接链接到要下载的文件的地址 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h1>通过链接下载文件&

  • JavaWeb动态导出Excel可弹出下载

    由于项目需求,需要将数据导出成Excel表格,并且可选择导出项,可下载.项目使用的Spring+Mybatis+SpringMVC框架,利用Apache POI导出Excel.POI具体使用请自行百度.话不多说,上代码. ExportExcelUtil代码 package com.rixin.common.util; import java.io.OutputStream; import java.lang.reflect.Method; import java.net.URLEncoder;

  • Java Web端程序实现文件下载的方法分享

    Web文件下载有两种,一种是文件在网站目录下,在浏览器中直接输入文件路径即可下载,如http://www.xxx.com/file.zip.另外一种是文件不在网站目录下或者文件是动态生成的(导出报表或者导出excel等),这种情况需要通过response的OutputStream实现文件的下载.DownloadUtils是一个Java Web文件下载工具类,提供多种静态方法实现文件下载. package com.rhui.util; import java.io.BufferedInputStr

  • JavaWeb响应下载功能实例代码(包含工具类)

    今天通过本文给大家分享是关于javaweb的响应(response)下载 以下是我的Demo: 页面我就粘主要部分的代码 <a href = "${pageContext.request.contextPath }/user/courseTab">模板下载</a> 当然,现在的项目大家都使用框架,这里我使用的是(SSM),好了,粘代码 @Controller @RequestMapping("/user") public class Uplo

  • javaweb文件打包批量下载代码

    本文实例为大家分享了javaweb文件打包批量下载,供大家参考,具体内容如下 // 批量下载未批改作业 @RequestMapping(value = "/downloadAllHomework", method = RequestMethod.GET) public void downloadAllHomework(HttpSession httpSession, HttpServletRequest request, HttpServletResponse response, St

  • java web项目实现文件下载实例代码

    复制代码 代码如下: File file = new File(path);// path是根据日志路径和文件名拼接出来的    String filename = file.getName();// 获取日志文件名称    InputStream fis = new BufferedInputStream(new FileInputStream(path));    byte[] buffer = new byte[fis.available()];    fis.read(buffer); 

  • java图形验证码生成工具类 web页面校验验证码

    最近做验证码,参考网上案例,发现有不少问题,特意进行了修改和完善. 验证码生成器: import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Date; import ja

  • java数据库唯一id生成工具类

    本文实例为大家分享了java数据库唯一id生成工具类的具体代码,供大家参考,具体内容如下 import java.io.File; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Map; import java.util.Random; import java.util.UUID; import org.springframework.dao.EmptyResultDataAccessExce

  • Java操作pdf的工具类itext的处理方法

    目录 一.什么是iText? 二.引入jar 三.iText常用类 四.生成PDF步骤 五.Java操作pdf的工具类itext 六.更多的Java代码实例 一.什么是iText? 在企业的信息系统中,报表处理一直占比较重要的作用,iText是一种生成PDF报表的Java组件.通过在服务器端使用Jsp或JavaBean生成PDF报表,客户端采用超链接显示或下载得到生成的报表,这样就很好的解决了B/S系统的报表处理问题. 二.引入jar 1.项目要使用iText,必须引入jar包 <depende

  • React Native验证码倒计时工具类分享

    本文实例为大家分享了React Native验证码倒计时工具类的具体代码,供大家参考,具体内容如下 因为以前直接用定时器,没去计算当前的时候,每次退出程序的时候,定时器一直不走,这个工具类简单的解决程序退出后台,定时器不走的bug,那么,直接上代码咯~~ /** * Created by zhuang.haipeng on 2017.9.11 * * 广告倒计时,验证码倒计时工具类 * * 用法: //60 * 1000 为60秒 , 60 * 60 * 100 为60分钟 ... * let

  • Java常用的时间工具类实例

    本文实例讲述了Java常用的时间工具类.分享给大家供大家参考,具体如下: package org.zhy.date; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; /** * 时间类型工具类 * * @author zhengyi * */ pu

  • Java实现的分页工具类与用法示例

    本文实例讲述了Java实现的分页工具类与用法.分享给大家供大家参考,具体如下: 今天闲来没事,写了一个页面的分页工具类,具有很好的兼容性与实用性哦. 不管怎么样,先来瞧一瞧: package com.bw.utils; /** * 分页工具类 * * @author H.ros * */ public class PageUtils2 { // 当前页(从页面获取的当前页码,未计算) private int currentPage; // 前一页 private int prevPage; //

  • Java实现RSA加密工具类

    公钥加密算法,也就是 非对称加密算法,这种算法加密和解密的密码不一样,一个是公钥,另一个是私钥: 公钥和私钥成对出现 公开的密钥叫公钥,只有自己知道的叫私钥 用公钥加密的数据只有对应的私钥可以解密 用私钥加密的数据只有对应的公钥可以解密 如果可以用公钥解密,则必然是对应的私钥加的密 如果可以用私钥解密,则必然是对应的公钥加的密 公钥和私钥是相对的,两者本身并没有规定哪一个必须是公钥或私钥. 代码如下 package com.cxy.template.controller.keyTools; im

  • java中封装JDBC工具类的实例分析

    对于能够重复使用的代码,我们最好的方法是对它们进行封装,然后在下次使用的使用就可以直接调用了.本篇所要提到的是JDBC工具类,相信大家在学习java时都接触过.那么对于封装它的方法,本篇先对工具类进行简单的说明,列出有关的封装步骤,然后带来相关的实例. 1.说明 在java开发过程中,代码中时常用到一些Scanner.Random一样的类,他们是键盘录入,生成随机数的类,像一个工具一样,在java中被称为工具类. 2.步骤 封装JDBC工具类 加入获取数据库连接对象的方法 加入释放连接的方法 3

  • Java基础之颜色工具类(超详细注释)

    颜色工具类(超详细注释) 设置属性值自动格式化rgb值和十六进制颜色值. import java.util.HashMap; import java.util.Map; public class Color{ private final String[] hex_letters = {"0", "1", "2", "3", "4", "5", "6", "7

  • Java线程的并发工具类实现原理解析

    目录 一.fork/join 1. Fork-Join原理 2. 工作窃取 3. 代码实现 二.CountDownLatch 三.CyclicBarrier 四.Semaphore 五.Exchange 六.Callable.Future.FutureTask 在JDK的并发包里提供了几个非常有用的并发工具类.CountDownLatch.CyclicBarrier和Semaphore工具类提供了一种并发流程控制的手段,Exchanger工具类则提供了在线程间交换数据的一种手段.本章会配合一些应

随机推荐