javaweb-简单的验证码和算术验证码

(1)我们登陆网站时,每次都会填写一些验证码,这些验证码的作用:防止被恶意攻击,验证码上面的字母数字一般都是随机生成的,因此我们首先要写一个方法生成一个随机的字符串,这里就需要java里面的随机函数Random,一般情况下我们将需要的字母数字放到一个静态的字符串中,让在随机生成一个数字下标,然后得到一个字符,验证码需要几个字符我们就生成几个字符。

(2)市面上的验证码一般都是以图片展示出来,因此我们需要一个图片的数据流,生成一个矩形的.jpg格式的图片。具体的代码展示:

package com.imooc.code;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;


public class CapchCode {
	public static String stringcode ="ABCDEFGHIJKLMNOPQISTUVWXYZ1234567890";
    public static Random random = new Random(); 
    
    
    public static String drawImage(HttpServletResponse response){
    	//1,得到随机生成的字符串
    	String code = drawString().toString();
    	//定义图片的宽度和高度
    	int height =25;
    	int width = 70;
    	//2。创建一个图片流
    	BufferedImage  CodeImage = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR);
        	
    	 //3:获取到 Graphics2D 绘制对象,开始绘制验证码
        Graphics2D graphics2D = CodeImage.createGraphics();
        //设置字体和颜色
        Font font = new Font("微软雅黑", Font.PLAIN, 20);
        Color color = new Color(0,0,0);
        graphics2D.setColor(color);
        graphics2D.setFont(font);
        //设置背景
        graphics2D.setBackground(new Color(226,226,240));
        
        //开始绘制对象的位置与长宽
        graphics2D.clearRect(0,0,width,height);
        //绘制形状,获取矩形对象
      //绘制形状,获取矩形对象
        FontRenderContext context = graphics2D.getFontRenderContext();
        Rectangle2D bounds = font.getStringBounds(code,context);
        
        double x = (width - bounds.getWidth())/2;
        double y = (height - bounds.getHeight())/2;
        
        double ascent = bounds.getY();
        double baseY = y - ascent;
        graphics2D.drawString(code,(int)x,(int)baseY);
        //结束绘制
        graphics2D.dispose();
        try {
            ImageIO.write(CodeImage,"jpg",response.getOutputStream());
            //刷新响应流
            response.flushBuffer();
        }catch(Exception ex){
            ex.printStackTrace();
        }
		return code;
    }
    
    //产生一个Stringbuffer的字符串 
    public static StringBuffer drawString(){
    StringBuffer buffer = new StringBuffer();
    for(int i=0;i<4;i++)
    	buffer.append(stringchar());
    return buffer;
    }
    //随机产生一个字母
    public static char stringchar(){
    	return stringcode.charAt(random.nextInt(stringcode.length()));
    }
}

(3)我们有时候登陆的时候,会遇到验证码看不清,或者不确定的情况下,需要重新生成一个有效的验证码。但是现在一般的浏览器都有记忆存储的功能,我们第一次生成一个验证码,如果不进行清除,那么就会一直展示第一个验证码,因此需要一个jsp来清理缓存。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@page import="com.imooc.code.CapchCode" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%

	//1:清空浏览器缓存,目的是为了清空浏览器的缓存,因为浏览器
	//会对网站的资源文件和图像进行记忆存储,如果被浏览器加载过的图片就记忆起来,记忆以后
	//文件就不会和服务器在交互,如果我们验证不清空的话可能会造成一个问题就是:验证刷新以后没有效果。
	response.setHeader("pragma","no-cache");
	response.setHeader("cache-control","no-cache");
	response.setHeader("expires","0");
	
	//2:调用编写的生成验证码的工具
	String code = CapchCode.drawImage(response);
	session.setAttribute("code",code);
	
	//3:如何解决getOutputStream异常问题
	out.clear();
	out = pageContext.pushBody();
%>

(4) 最后将生成的验证码展示出来:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
  <head>
    <title>java验证码</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
  </head>
  <body>

     <img src="code.jsp" alt="" id="code">
     <a href="javascript:void(0);" onclick="changeCode()">看不清?点我</a>
     <script>
         
         function changeCode() {
             document.getElementById("code").src = "code.jsp?d="+new Date().getTime();
         }

     </script>
  </body>
</html>

( 5)结果展示:

 (6)算术验证码:算术验证码较之上面多了一个干扰线的设置,其余的没有特别的设置。

主要代码展示:

package com.imooc.code;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;


public class CapchCode {
   /*
    * 算术验证码的实现
    */
	public static String drawImageVerificate(HttpServletResponse response){
		//设置长宽
		int width=100,height=30;
		//在内存中创建图片
		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		// 创建图片的上下文 
		Graphics2D g = image.createGraphics();
		// 创建随机对象,此随机对象主要运用于算术表达式的数字
		Random random = new Random();
		//随机设置背景颜色
		g.setColor(getRandomColor(240,250));
		g.setFont(new Font("微软雅黑", Font.PLAIN, 22));
		//开始绘制
		g.fillRect(0, 0, width, height);
		g.setColor(getRandomColor(180,230));
		//主要的部分,设置干扰线,绘制线条到干扰线中
		for(int i=0;i<10;i++){
		   int sx =  random.nextInt(width);
		   int sy = random.nextInt(height);
		   int dx = random.nextInt(60);
		   int dy = random.nextInt(60);
		   g.drawLine(sx,sy, dx, dy);
		}
		// 对算术表达式的拼接
		int num1 = (int)(Math.random()*10+1);
		int num2 = (int)(Math.random()*10+1);
		int result=0;
		int fuhao = random.nextInt(3);
		String fuhaostr = "";
		switch (fuhao) {
		case 1:
			result = num1+num2;
			fuhaostr = num1+" + "+num2+" = ?";
			break;
        case 2:
        	result = num1 - num2 ;
        	fuhaostr = num1+" - "+num2+" = ?";
        case 3:
        	result = num1 * num2;
        	fuhaostr = num1 +" * "+num2+" = ?";
			break;
		}
		
		// 设置随机颜色
		g.setColor(new Color(20+random.nextInt(110), 20+random.nextInt(110),20+random.nextInt(110)));
		// 绘制表达式
		g.drawString(fuhaostr, 5, 25);
		//结束绘制
		g.dispose();
		try{
			//输出图片到页面
			
			ImageIO.write(image, "JPEG", response.getOutputStream());
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
 		return null;
	}
    public static Color getRandomColor(int fa,int bc){
        if(fa>255)fa=255;
        if(bc>255)bc=255;
    	
    	Random random = new Random();
        int r = fa +random.nextInt(bc-fa);
        int g = fa +random.nextInt(bc-fa);
        int b = fa +random.nextInt(bc-fa);
        	return new Color(r,g,b);
    }	
}

结果展示:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值