轻松学会网页中验证码的生成(JAVA)

验证码生成的基本流程

1.验证码的生成,我们能够看到是用Graphics对象画出来的。对象我们必须要获得Graphics对象

1-1,Graphics对象的获取,要通过BufferedImage获得

<span style="font-size:18px;">int width=100;//确定框框的大小
	int height=40;
	BufferedImage bfi =new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
	Graphics g=bfi.getGraphics();//获得Graphics对象就可以画图</span>

1-2,一般的验证码背景框都是白色的

<span style="font-size:18px;">	//1,设置背景(白框框)
	g.setColor(Color.WHITE);//白色的画笔
	g.fillRect(0, 0, width, height);//画矩形矩形框框</span>

1-3,保存数据(后台验证使用)和设置字体样式(美观)

String str="";//保存数据
	Random rom=new Random();
	//设置字体的大写与粗
	g.setFont(new Font("a",	 Font.BOLD,20));

1-4.生成具体的数值,以及随机生成的颜色

for(int i=0;i<4;i++){
		int num=rom.nextInt(10);//生成的随机数
		g.setColor(new Color(rom.nextInt(256),rom.nextInt(256), rom.nextInt(256)));//设置画笔的颜色(随机)
		g.drawString(""+num, 20*i, 20+rom.nextInt(10));//画出线,x的位置每一之间增加20,y的坐标以20一条线,在线上或者是线下
		//PS:位置需要明确些,
	}

1-5.一般的数字容易被其他软件直接识别出来,为了防黑。稍微加一点干扰线

//画出一些干扰线
	for (int i = 0; i < 10; i++) {
		g.setColor(new Color(rom.nextInt(256),rom.nextInt(256), rom.nextInt(256)));//设置画笔的颜色(随机)
		g.drawLine(rom.nextInt(100),rom.nextInt(40), rom.nextInt(100), rom.nextInt(40));//位置也是随机,x,y的值不要超过矩形框框
	}

1-6.销毁Graphics对象和存储图片

<span style="white-space:pre">	</span>g.dispose();//销毁对象
	ImageIO.write(bfi, "JPEG", res.getOutputStream());//图片用字节流 直接得到  PS::: res是Servlet里面的。

这样验证码就生成了,那我们如何导入到前台去呢

2,具体实现

前台代码呈现():

<body>
    	<h1>用户登录</h1><br/>
    	用户名:<input type="text" name="nametext"/><br/>
    	密   码:<input type="text" name="psd"/><br/>
    	请输入验证码:<input type="text"/>
    	<img <span style="color:#ff0000;">src="/IMG/immg" </span>id="aid"/><a href="javascript:flush()" >看不清</a>
  </body>

src的地址来源就是从后台发过来的。路径是很有意思的。

2-1
步骤

项目里面
myeclipse --> src -->new  Servlet 出现如下:

点击----》next 出现如下页面:

这个配置会自动到项目里面的web-INF文件夹里面web.xml。这个框框里面的值就是前台 src里面写的需要访问的路径,----> 点击完成就行了。

自动了。生成如下界面:

在这里就可写之前的代码。但是需要注意,我们必须通过覆盖这个方法才能有效:

protected void service(HttpServletRequest req, HttpServletResponse resp)//自动生成 输入 <span style="font-family: Arial, Helvetica, sans-serif;">service  补全,自动生成</span>

		throws ServletException, IOException {
	// TODO Auto-generated method stub
	super.service(req, resp);
}

具体的代码如下:

package cn.hncu.com.servlet;

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

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Imgdemo extends HttpServlet {
@Override
public void service(ServletRequest req, ServletResponse res)
		throws ServletException, IOException {
	int width=100;//确定框框的大小
	int height=40;
	BufferedImage bfi =new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
	Graphics g=bfi.getGraphics();//获得Graphics对象就可以画图
	//1,设置背景(白框框)
	g.setColor(Color.WHITE);//白色的画笔
	g.fillRect(0, 0, width, height);//画矩形矩形框框
	//2,具体生成随机数
	String str="";//保存数据
	Random rom=new Random();
	//设置字体的大写与粗
	g.setFont(new Font("a",	 Font.BOLD,20));
	//画出具体的图片

	for(int i=0;i<4;i++){
		int num=rom.nextInt(10);//生成的随机数
		g.setColor(new Color(rom.nextInt(256),rom.nextInt(256), rom.nextInt(256)));//设置画笔的颜色(随机)
		g.drawString(""+num, 20*i, 20+rom.nextInt(10));//画出线,x的位置每一之间增加20,y的坐标以20一条线,在线上或者是线下
		//PS:位置需要明确些,
	}
	//画出一些干扰线
	for (int i = 0; i < 10; i++) {
		g.setColor(new Color(rom.nextInt(256),rom.nextInt(256), rom.nextInt(256)));//设置画笔的颜色(随机)
		g.drawLine(rom.nextInt(100),rom.nextInt(40), rom.nextInt(100), rom.nextInt(40));//位置也是随机,x,y的值不要超过矩形框框
	}
	g.dispose();
	ImageIO.write(bfi, "JPEG", res.getOutputStream());//图片用字节流 直接得到
}
}<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">	</span>

前台代码:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">

    <title>My JSP 'img.jsp' starting page</title>

	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
	<script type="text/javascript">

		function flush(){
		var text=document.getElementById("aid");
		var date =new Date();
		var tt=date.getTime();
		text.src="/IMG/immg?"+tt;

		}
	</script>

  </head>

  <body>
    	<h1>用户登录</h1><br/>
    	用户名:<input type="text" name="nametext"/><br/>
    	密   码:<input type="text" name="psd"/><br/>
    	请输入验证码:<input type="text"/>
    	<img src="/IMG/immg" id="aid"/><a href="javascript:flush()" >看不清</a>
  </body>
</html>

对于前台代码需要解释一下:

当我们的的验证码传过来看不清的时候需要刷新,而浏览器有自动记忆的功能,当没有新的参数传进来的时候,浏览器是不会刷新的,所以我们需要手动的去写一个js控制参数传,我们知道,只有时间是不会变化的,所有我们采用时间来作为参数传递。

PS:自己坑了一段时间的问题:验证码的路径问题。前端的“/”表示 tomcat目录,在项目内部,如web.xml中“/”表示该项目下。也就是说,他们两个的目录差了一层。

最后附上自己在测试的时候的代码以及修改数字形状的问题,如改成2D的效果更不错。都有很明显的记录。

package cn.hncu.com;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;

import org.junit.Test;

public class Demoimg {
	@Test
	public void Test() throws Exception{
		String str="9988";
		int width=60;
		int height=30;
		//通过bufferedImage对象获得Graphics对象
		BufferedImage bfi=new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
		Graphics g=bfi.getGraphics();
		g.drawString(str, 10,10);
		g.dispose();//类似于IO中的关流
		ImageIO.write(bfi	, "JPEG", new FileOutputStream("F:\\ex\\a.jpg"));
		//bfi为画布,将画布写到文件中JPEG为指定文件格式
	}

	@Test
	public void Test2() throws Exception{
		int width=100;
		int height=40;
		BufferedImage bfi =new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		Graphics g=bfi.getGraphics();//获得Graphics对象就可以画图
		//1,设置背景(白框框)
		g.setColor(Color.WHITE);//白色的画笔
		g.fillRect(0, 0, width, height);
		//2,具体生成随机数
		String str="";//保存数据
		Random rom=new Random();
		//设置字体的大写与粗
		g.setFont(new Font("a",	 Font.BOLD,20));
		//画出具体的图片

		for(int i=0;i<4;i++){
			int num=rom.nextInt(10);//生成的随机数
			g.setColor(new Color(rom.nextInt(256),rom.nextInt(256), rom.nextInt(256)));//设置画笔的颜色(随机)
			g.drawString(""+num, 20*i, 20+rom.nextInt(10));//画出线,x的位置每一之间增加20,y的坐标以20一条线,在线上或者是线下
			//PS:位置需要明确些,
		}
		//画出一些干扰线
		for (int i = 0; i < 10; i++) {
			g.setColor(new Color(rom.nextInt(256),rom.nextInt(256), rom.nextInt(256)));//设置画笔的颜色(随机)
			g.drawLine(rom.nextInt(100),rom.nextInt(40), rom.nextInt(100), rom.nextInt(40));//位置也是随机,x,y的值不要超过矩形框框
		}
		g.dispose();
		ImageIO.write(bfi, "JPEG", new FileOutputStream("F:\\ex\\b.jpg"));
	}

	//画出可以变化的情况
	//字体能够旋转的验证码
	@Test
	public void Test3() throws IOException{
		int width=100;
		int height=40;
		BufferedImage bfi =new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		Graphics g=bfi.getGraphics();
		Graphics2D g2d=(Graphics2D) g;
		Random rom =new Random();
		g2d.setColor(Color.WHITE);//设置画笔的颜色
		g2d.fillRect(0, 0, width, height);//画出一个白色的矩形
		g2d.setFont(new Font("a", Font.BOLD, 20));
		for(int i=0;i<4;i++){
			int num=rom.nextInt(10);
			//旋转,放缩
			AffineTransform aff=new AffineTransform();
			//aff.rotate(Math.random(), i*18, height-20);//旋转
			aff.scale(0.6+Math.random(), 0.6+Math.random());//缩放
			g2d.setColor(new Color(rom.nextInt(256),rom.nextInt(256),rom.nextInt(256)));
			g2d.setTransform(aff);
			g2d.drawString(""+num, i*18, height-25);
		}
		g2d.dispose();
		ImageIO.write(bfi, "JPEG", new FileOutputStream("F:\\ex\\c.jpg"));

	}
}

版权声明:本文为博主原创文章,未经博主允许不得转载。希望大家多指教指教

时间: 2024-08-24 02:41:39

轻松学会网页中验证码的生成(JAVA)的相关文章

struts2中验证码的生成和使用

第一步生产字符串: package com.yancode.demo; import java.util.Arrays; /* * 一步一步来,要生成验证码图片,首先要有验证码,然后才能在画在图片上.为了能够灵活控制验证码, * 特别编写了SecurityCode类,它向外提供随机字符串.并且可以控制字符串的长度和难度. * SecurityCode类中提供的验证码分三个难度,易(全数字).中(数字+小写英文).难(数字+大小写英文). * 难度使用枚举SecurityCodeLevle表示,避

Android开发中验证码的生成

近期在做电商金融类的项目,验证码的生成方法不可缺少.先学习了一种.经过測试好用.从别处学习的代码,稍修改了一下可选择是否支持识别大写和小写.直接上代码. import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.EditText; import android.wid

frame框架中验证码图片抓取(VB2010)

今日写一个验证码识别自动登录的程序,发现网页中验证码图片是嵌在frame框架中,一时间遇到了问题无法搞定,网上搜了很多网页也没有具体的解决办法,今日偶然尝试居然搞定了,给大家分享一下. HTML的源程序模拟如下: <body> <iframe src="hello.jpg"></iframe> </body> 真实的场景SRC是一个类似于checkcode.ASP的链接,不能直接通过WEB地址抓取,不然图片就会变了,这个估计大家都知道,抓

SpringMvc项目中使用GoogleKaptcha 生成验证码

SpringMvc项目中使用GoogleKaptcha 生成验证码 前言:google captcha 是google生成验证码的一个工具类,其原理是将随机生成字符串保存到session中,同时以图片的形式返回给页面,之后前台页面提交到后台进行对比. 1.jar包准备 官方提供的pom应该是 <dependency> <groupId>com.google.code.kaptcha</groupId> <artifactId>kaptcha</arti

在springmvc项目中使用kaptcha生成验证码

Kaptcha验证码 下载kaptcha-2.3.2.jar http://code.google.com/p/kaptcha/downloads/list 1.spring 配置文件 applicationContext.xml [html]          <bean id="captchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha">           <pro

关于网页中不刷新页面改变验证码的两种方法

今天做一个注册的页面,需要输入验证码.验证码的生成是动态的,不过要刷新页面,才能改变验证码,因为刷新后浏览器会向服务器提交新的请求,服务器就动态生成新的验证码响应给浏览器.为了能够在不刷新页面的情况下改变验证码,需要JavaScript的支持. 第一种方法是在请求地址后面带参数,这是一个小窍门.因为浏览器访问服务器的时候地址后面可以带上参数一起传给服务器,而加载内容是只看地址不看后面的参数:另外在<img src="地址"/>中,只要浏览器发现地址改变了就会自动重新加载该地

Java使用正则表达式取网页中的一段内容(以取Js方法为例)

关于正则表达式: 表1.常用的元字符 代码 说明 . 匹配除换行符以外的任意字符 \w 匹配字母或数字或下划线或汉字 \s 匹配任意的空白符 \d 匹配数字 \b 匹配单词的开始或结束 ^ 匹配字符串的开始 $ 匹配字符串的结束 表2.常用的限定符 代码/语法 说明 * 重复零次或更多次 + 重复一次或更多次 ? 重复零次或一次 {n} 重复n次 {n,} 重复n次或更多次 {n,m} 重复n到m次 表3.常用的反义代码 代码/语法 说明 \W 匹配任意不是字母,数字,下划线,汉字的字符 \S

通过js动态生成文本框,怎么把文本框中的值传到java后台?

通过js动态生成文本框,怎么把文本框中的值传到java后台? 1 var lengths; 2 function insertrow2() //增加的一行方法2 3 { 4 newRow=document.all.yltable.insertRow(-1); 5 lengths = document.all.yltable.rows.length; 6 7 newcell=newRow.insertCell() ; 8 newRow.bgColor='#FFFFFF'; 9 newcell.al

java如何在网页中提取Email地址

开博好久了,今天第一次发表技术文档,之前总是将一些好的事例保存在电脑,时间久了找起来也很麻烦,所以还是放在博客里进行归类比较方便,这样也能将自己在学习过程中的一些心得体会分享给大家,也能给需要的人一点帮助. 一个朋友需要我帮忙给写一个能够提取网页中Email地址的小程序,所以就用Java语言帮他做了一个,有不完善的地方还请大家谅解,并提出来,一起学习. 源代码详见附件!加压后将将readme.htm放在F:\\share\\readme.htm,也可自定义目录,自定义目录需要修改对应的代码文件路