怎样用java实现验证码

Python015

怎样用java实现验证码,第1张

现在许多系统的注册 登录或者发布信息模块都添加的随机验证码功能 就是为了避免自动注册程序或者自动发布程序的使用

验证码实际上就是随机选择一些字符以图片的形式展现在页面上 如果进行提交操作的同时需要将图片上的字符同时提交 如果提交的字符与服务器session保存的不同 则认为提交信息无效 为了避免自动程序分析解析图片 通常会在图片上随机生成一些干扰线或者将字符进行扭曲 增加自动识别验证码的难度

在这里 我们使用java实现验证码

<%@ page contentType= image/jpeg import= java awt * java awt image * java util * javax imageio * %>

<%!

Color getRandColor(int fc int bc){//给定范围获得随机颜色

Random random = new Random()

if(fc>) fc=

if(bc>) bc=

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)

}

%>

<%

//设置页面不缓存

response setHeader( Pragma No cache )

response setHeader( Cache Control no cache )

response setDateHeader( Expires )

// 在内存中创建图象

int width= height=

BufferedImage image = new BufferedImage(width height BufferedImage TYPE_INT_RGB)

// 获取图形上下文

Graphics g = image getGraphics()

//生成随机类

Random random = new Random()

// 设定背景色

g setColor(getRandColor( ))

g fillRect( width height)

//设定字体

g setFont(new Font( Times New Roman Font PLAIN ))

// 随机产生 条干扰线 使图象中的认证码不易被其它程序探测到

g setColor(getRandColor( ))

for (int i= i<i++)

{

int x = random nextInt(width)

int y = random nextInt(height)

int xl = random nextInt( )

int yl = random nextInt( )

g drawLine(x y x+xl y+yl)

}

// 取随机产生的认证码( 位数字)

String codeList = ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

String sRand=

for (int i= i<i++){

int a=random nextInt(codeList length() )

String rand=codeList substring(a a+ )

sRand+=rand

// 将认证码显示到图象中

g setColor(new Color( +random nextInt( ) +random nextInt( ) +random nextInt( )))//调用函数出来的颜色相同 可能是因为种子太接近 所以只能直接生成

g drawString(rand *i+ )

}

// 将认证码存入SESSION

session setAttribute( rand sRand)

// 图象生效

g dispose()

// 输出图象到页面

ImageIO write(image JPEG response getOutputStream())

out clear()

out = pageContext pushBody()

lishixinzhi/Article/program/Java/hx/201311/25536

原理:

1.随机生成4个数字 用到了Random类

2.对这4个数字设置字体格式 用 setFont方法

3.改变字体颜色用setColor 然后随机生成颜色

代码如下

package s1

import java.awt.Color

import java.awt.Font

import java.awt.Graphics

import java.awt.image.BufferedImage

import java.io.IOException

import java.io.PrintWriter

import java.util.Random

import javax.imageio.ImageIO

import javax.jms.Session

import javax.servlet.ServletException

import javax.servlet.http.HttpServlet

import javax.servlet.http.HttpServletRequest

import javax.servlet.http.HttpServletResponse

import javax.servlet.http.HttpSession

public class GetImage extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

this.doPost(request, response)

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

// 发送图片不能够添加这2行代码

// response.setContentType("text/htmlcharset=UTF-8")

//request.setCharacterEncoding("UTF-8")

int width=100

int height=50

//获得一张图片

BufferedImage image=new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB)

Graphics g=image.getGraphics()

g.setColor(Color.WHITE)

g.fillRect(1, 1, width-2, height-2)

g.setFont(new Font("宋体",Font.BOLD,30))

Random random=new Random()

//填充的字符串

String str="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"

//缓存生成的验证码

StringBuffer stringbuffer=new StringBuffer()

//随机生成验证码的颜色和字符

for(int i=0i<4i++)

{ //设置随机颜色

g.setColor(new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256)))

int index=random.nextInt(62)//这里的62就是从填充字符段中随意选取一个位置

String str1=str.substring(index,index+1)

g.drawString(str1, 20*i, 30)//x,y数值设置太小会显示不出来

stringbuffer.append(str1)

}

//将生成的验证码存到服务器

request.getSession().setAttribute("checkcode", stringbuffer.toString())//key和value

//将图片发送给浏览器

ImageIO.write(image, "jpg", response.getOutputStream())

}

}

用户登录界面代码

package s1

import java.io.IOException

import java.io.PrintWriter

import javax.servlet.ServletException

import javax.servlet.http.HttpServlet

import javax.servlet.http.HttpServletRequest

import javax.servlet.http.HttpServletResponse

import javax.servlet.http.HttpSession

public class Login extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/htmlcharset=UTF-8")// 设置服务器发送给浏览器的编码方式

request.setCharacterEncoding("UTF-8")// 客户端向服务器提交的数据的解码方式

// 获得用户提交的数据

String checkcode = request.getParameter("checkcode")

System.out.println(checkcode)

// 判断输入的验证码是不是符合

HttpSession session = request.getSession()// session是存放数据的地方

String str = (String) session.getAttribute("checkcode")

if (str != null) {

if (checkcode.compareToIgnoreCase(str) == 0) // 验证码忽略大小写

response.getWriter().println("验证码输入正确")

else

response.getWriter().println("验证码输入错误")

}

else response.getWriter().println("验证码失效")

// 使用完的验证码信息要删除,返回原页面再输一次,验证码就失效了

session.removeAttribute("checkcode")

}

}

1、创建一个Http的模拟请求工具类,然后写一个POST方法或者GET方法

/** * 文件说明 * @Description:扩展说明 * @Copyright: XXXX dreamtech.com.cn Inc. All right reserved * @Version: V6.0 */package com.demo.utilimport java.io.IOExceptionimport java.util.Mapimport org.apache.commons.httpclient.HttpClientimport org.apache.commons.httpclient.HttpExceptionimport org.apache.commons.httpclient.SimpleHttpConnectionManagerimport org.apache.commons.httpclient.methods.GetMethodimport org.apache.commons.httpclient.methods.PostMethod/** * @Author: feizi * @Date: XXXX年XX月XX日 XX:XX:XX * @ModifyUser: feizi * @ModifyDate: XXXX年XX月XX日 XX:XX:XX * @Version:V6.0 */public class HttpRequestUtil { /** * HttpClient 模拟POST请求 * 方法说明 * @Discription:扩展说明 * @param url * @param params * @return String * @Author: feizi * @Date: XXXX年XX月XX日 XX:XX:XX * @ModifyUser:feizi * @ModifyDate: XXXX年XX月XX日 XX:XX:XX */ public static String postRequest(String url, Map<String, String>params) { //构造HttpClient的实例 HttpClient httpClient = new HttpClient() //创建POST方法的实例 PostMethod postMethod = new PostMethod(url) //设置请求头信息 postMethod.setRequestHeader("Connection", "close") //添加参数 for (Map.Entry<String, String>entry : params.entrySet()) { postMethod.addParameter(entry.getKey(), entry.getValue()) } //使用系统提供的默认的恢复策略,设置请求重试处理,用的是默认的重试处理:请求三次 httpClient.getParams().setBooleanParameter("http.protocol.expect-continue", false) //接收处理结果 String result = null try { //执行Http Post请求 httpClient.executeMethod(postMethod) //返回处理结果 result = postMethod.getResponseBodyAsString() } catch (HttpException e) { // 发生致命的异常,可能是协议不对或者返回的内容有问题 System.out.println("请检查输入的URL!") e.printStackTrace() } catch (IOException e) { // 发生网络异常 System.out.println("发生网络异常!") e.printStackTrace() } finally { //释放链接 postMethod.releaseConnection() //关闭HttpClient实例 if (httpClient != null) {((SimpleHttpConnectionManager) httpClient.getHttpConnectionManager()).shutdown() httpClient = null } } return result} /** * HttpClient 模拟GET请求 * 方法说明 * @Discription:扩展说明 * @param url * @param params * @return String * @Author: feizi * @Date: XXXX年XX月XX日 XX:XX:XX * @ModifyUser:feizi * @ModifyDate: XXXX年XX月XX日 XX:XX:XX */ public static String getRequest(String url, Map<String, String>params) { //构造HttpClient实例 HttpClient client = new HttpClient() //拼接参数 String paramStr = "" for (String key : params.keySet()) { paramStr = paramStr + "&" + key + "=" + params.get(key) } paramStr = paramStr.substring(1) //创建GET方法的实例 GetMethod method = new GetMethod(url + "?" + paramStr) //接收返回结果 String result = null try { //执行HTTP GET方法请求 client.executeMethod(method) //返回处理结果 result = method.getResponseBodyAsString() } catch (HttpException e) { // 发生致命的异常,可能是协议不对或者返回的内容有问题 System.out.println("请检查输入的URL!") e.printStackTrace() } catch (IOException e) { // 发生网络异常 System.out.println("发生网络异常!") e.printStackTrace() } finally { //释放链接 method.releaseConnection() //关闭HttpClient实例 if (client != null) {((SimpleHttpConnectionManager) client.getHttpConnectionManager()).shutdown() client = null } } return result}}

2、在创建一个类,生成验证码,然后传递相应的参数(不同的短信平台接口会有不同的参数要求,这个一般短信平台提供的接口文档中都会有的,直接看文档然后按要求来即可)

/** * 文件说明 * @Description:扩展说明 * @Copyright: XXXX dreamtech.com.cn Inc. All right reserved * @Version: V6.0 */package com.demo.utilimport java.net.URLEncoderimport java.util.HashMapimport java.util.Map/** * @Author: feizi * @Date: XXXX年XX月XX日 XX:XX:XX * @ModifyUser: feizi * @ModifyDate: XXXX年XX月XX日 XX:XX:XX * @Version:V6.0 */public class SendMsgUtil { /** * 发送短信消息 * 方法说明 * @Discription:扩展说明 * @param phones * @param content * @return * @return String * @Author: feizi * @Date: 2015年4月17日 下午7:18:08 * @ModifyUser:feizi * @ModifyDate: 2015年4月17日 下午7:18:08 */ @SuppressWarnings("deprecation") public static String sendMsg(String phones,String content){ //短信接口URL提交地址 String url = "短信接口URL提交地址" Map<String, String>params = new HashMap<String, String>() params.put("zh", "用户账号") params.put("mm", "用户密码") params.put("dxlbid", "短信类别编号") params.put("extno", "扩展编号") //手机号码,多个号码使用英文逗号进行分割 params.put("hm", phones) //将短信内容进行URLEncoder编码 params.put("nr", URLEncoder.encode(content)) return HttpRequestUtil.getRequest(url, params)} /** * 随机生成6位随机验证码 * 方法说明 * @Discription:扩展说明 * @return * @return String * @Author: feizi * @Date: 2015年4月17日 下午7:19:02 * @ModifyUser:feizi * @ModifyDate: 2015年4月17日 下午7:19:02 */ public static String createRandomVcode(){ //验证码 String vcode = "" for (int i = 0i <6i++) { vcode = vcode + (int)(Math.random() * 9) } return vcode} /** * 测试 * 方法说明 * @Discription:扩展说明 * @param args * @return void * @Author: feizi * @Date: XXXX年XX月XX日 XX:XX:XX * @ModifyUser:feizi * @ModifyDate: XXXX年XX月XX日 XX:XX:XX */ public static void main(String[] args) {// System.out.println(SendMsgUtil.createRandomVcode())// System.out.println("&ecb=12".substring(1)) System.out.println(sendMsg("18123456789,15123456789", "尊敬的用户,您的验证码为" + SendMsgUtil.createRandomVcode() + ",有效期为60秒,如有疑虑请详询XXX-XXX-XXXX【XXX中心】"))}

然后执行一下,一般的情况下参数传递正确,按照接口文档的规范来操作的话,都会发送成功的,手机都能收到验证码的,然后可能会出现的问题就是:发送的短信内容有可能会出现中文乱码,然后就会发送不成功,按照短信平台的要求进行相应的编码即可。一般都会是UTF-8编码。