验证码(图灵测试)

一:Code.java文件(servlet文件)
package main;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random;

import javax.imageio.ImageIO;
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 Code extends HttpServlet
{

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException
	{
		doPost(request,response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException
	{
		//回应为image
		 response.setContentType("image/jpeg");  
		 
		// 设置要画的图片的宽和高
		int width = 70;
		int height = 24;
		// 具有可访问图像数据缓冲区的Image
		BufferedImage image = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_RGB);
		// 创建两个画笔
		Graphics g = image.getGraphics();
		Graphics2D g2d = (Graphics2D) g;
		g.setColor(getColor(200, 240));// 上色
		g.fillRect(0, 0, width, height);// 全图绘制背景色

		// 在图片上绘制150条干扰线
		g.setColor(getColor(180, 200));// 上色
		Random random = new Random();
		for (int i = 0; i < 150; i++)
		{
			// 绘制线的坐标
			int x = random.nextInt(width - 1);
			int y = random.nextInt(height - 1);
			// x、y坐标偏移多少个单位
			int deltax = random.nextInt(6) + 1;
			int deltay = random.nextInt(12) + 1;
			// 构造一个具有指定属性的实心的 BasicStroke(2D图形)
			BasicStroke bs = new BasicStroke(2f, BasicStroke.CAP_BUTT,
					BasicStroke.JOIN_BEVEL);
			// Line2D是一个无法直接实例化的抽象类
			Line2D line = new Line2D.Double(x, y, x + deltax, y + deltay);
			g2d.setStroke(bs);// 绘制 BasicStroke
			g2d.draw(line);// 再绘制线条
		}

		// 输出那些字符,以便验证
		String str = "";
		int temp = 0;
		Font font = new Font("华文宋体", Font.BOLD, 14);
		g.setFont(font);// 设置画笔画的字体格式
		// 绘制四个字符
		for (int i = 0; i < 4; i++)
		{
			if (random.nextInt(2) == 1)
			{
				temp = random.nextInt(26) + 'A';
			}
			else
			{
				temp = random.nextInt(10) + '0';
			}
			char ctemp = (char) temp;
			str += ctemp;
			Color c=getColor(20,130);//颜色较深
			g.setColor(c);
			/** ******随机将文字缩放并旋转一定的角度****** */
			// 将文字旋转一定角度
			/*AffineTransform 类表示 2D 仿射变换,它执行从 2D 坐标到其他 2D 坐标的线性映射,
				保留了线的“直线性”和“平行性”。可以使用一系列
				平移 (translation)、缩放 (scale)、翻转 (flip)、旋转 (rotation) 和错切 (shear) 
				来构造仿射变换。*/ 
			AffineTransform trans=new AffineTransform();
			//45弧度,旋转点位置
			trans.rotate(random.nextInt(45) * Math.PI / 180, 15 * i + 10, 6);
			// 缩放文字
			float scaleSize=random.nextFloat()+0.5f;//缩放大小
			if(scaleSize<0.8f||scaleSize>1.2)
			{
				scaleSize=1.0f;
			}
			trans.scale(scaleSize, scaleSize);
			g2d.setTransform(trans);
			//画在什么位置
			g.drawString(ctemp+"", 15*i+10, 14);
			
		}
		
		//禁止图片缓存那样刷新就不会有重复的图片出现
		response.setHeader("Pragma", "No-cache");
		response.setHeader("Cache-Control", "No-cache");
		response.setDateHeader("Expires", 0);
		
		HttpSession session=request.getSession();
		session.setAttribute("BBScode", str);//把验证码发送到session以便验证
		try
		{
			//把得到的验证码保存称jpeg格式放在输入流中
			ImageIO.write(image, "jpeg", response.getOutputStream());
		}
		catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	// 得到具有规定的颜色
	public static Color getColor(int start, int end)
	{
		Random R = new Random();

		int r = start + R.nextInt(end - start);
		int g = start + R.nextInt(end - start);
		int b = start + R.nextInt(end - start);
		return new Color(r, g, b);
	}

}



二、在XML里配置
  <servlet>
    <servlet-name>code</servlet-name>
    <servlet-class>main.Code</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>code</servlet-name>
    <url-pattern>/code</url-pattern>
  </servlet-mapping>



三、code.jsp(显示页面)

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<html>
<head>
	<script language="javascript">
		function reloadcode()
    	{
    		var timenow = new Date().getTime();                  
    		document.getElementById("reqCode").src="../code?d="+timenow;
    	}

	</script>
<style type="text/css">
	body{
		 color:blue;                                
		 font-family:楷体;
		 text-align:center;    
		 background:cyan;
		 font-Size:24;
		 background-image: url(image/4.jpg);   
	  }
	.style1 {font-size: 15px}
</style>
<title>注册君临账号_君临论坛</title>
</head>
<body>

	<font color="olive" size="6" face="华文行楷">注册君临账号</font>
	<hr color="silver">
	<div align="left" class="style1"><a href="load.jsp">首页</a>>>注册页</div>
	
	
	<form action="checkmyindex.jsp" name="info" id="info">
	<center>
			   
		<img alt="验证码" name="reqCode" id="reqCode" src="<%=request.getContextPath() %>/code"/>
				<a href="JavaScript:reloadcode();">再换一张</a>
			<input type="text" name="xincode" size="15" />
				<% 
					String ssss=request.getParameter("codeerror");
					if(ssss!=null){
				%>
				<label id="codeError"><font color='red' size='-1'>您输入的验证码不正确!</font></label><br/>
				<% 	
					}
				%>
				<input type="submit" value="确定">
	</form>
      	 <hr color="gray">
      	 <font size="2" face="宋体">
      	 <a href="#">关于君临</a>|
      	 <a href="#">君临客服</a>|
      	 <a href="#">隐私和版权</a>|
      	 <a href="#">联系我们</a>|
      	 <a href="#">加入君临</a>|
      	 <a href="#">举报投诉</a>
      	 </font>
</body>
</html>



四、验证输入的验证码是否一致

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<html>
<head>
<title>验证BBS</title>
</head>
<body>
	<% 
		String yuancode=(String)session.getAttribute("BBScode");
		String xingcode=request.getParameter("xincode");
		if(xingcode.equals(yuancode)){
			response.sendRedirect("register.jsp");
		}else{
			response.sendRedirect("code.jsp?codeerror=4564641");
		}
	%>
	
</body>
</html>

你可能感兴趣的:(java,servlet,javaee,验证码)