javaweb实现一次性图片验证码

9 篇文章 0 订阅
2 篇文章 0 订阅

1 验证码有啥用

在我们注册时,如果没有验证码的话,我们可以使用URLConnection来写一段代码发出注册请求。甚至可以使用while(true)来注册!那么服务器就废了!

验证码可以去识别发出请求的是人还是程序!当然,如果聪明的程序可以去分析验证码图片!但分析图片也不是一件容易的事,因为一般验证码图片都会带有干扰线,人都看不清,那么程序一定分析不出来。

2、实现过程图解(两个请求)

3、首先是登录界面login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<script type="text/javascript">
function _change()
{
	var imgEle=document.getElementById("img");//得到img元素
	//修改其src为/day12/VerifyCodeServlet+随机参数
	imgEle.src="/day12/VerifyCodeServlet?a="+new Date().getTime();
}
</script>
<body>
<%
	String message="";
	String msg=(String)request.getAttribute("msg");
	if(msg!=null)
	{
		message=msg;
	}
%>
<h1>登录</h1><br/>
<font color="red"><b><%=message %></font>
<form action="/day12/LoginServlet" method="post">
	用户名:<input type="text" name="username" /><br/>
	密码:<input type="password" name="password" /><br/>
	验证码:<input type="text" name="verifyCode" size="4"/>
	<img src="/day12/VerifyCodeServlet" id="img">
	<a href="javascript:_change()">换一张</a>
	<br/>
	<input type="submit" value="登录" />	
</form>
</body>
</html>

4、验证码生成类

package ex01;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;

import javax.imageio.ImageIO;

public class VerifyCode {
	private int w=70;
	private int h=35;
	private Random r=new Random();//生成随机数,后面可以调用
	private String[] fontNames= {"宋体","华文楷体","微软雅黑","楷体","黑体"};
	//可选字符
	private String code= "23456789abcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNPQRSTUVWSYZ";
	private Color bgColor=new Color(255,255,255);//背景色
	private String text;//验证码上的文本
	
	//生成随机颜色
	private Color randomColor()
	{
		int red=r.nextInt(150);
		int green=r.nextInt(150);
		int blue=r.nextInt(150);
		return new Color(red,green,blue);
	}
	private Font randomFont()
	{
		int index=r.nextInt(fontNames.length);
		String fontName=fontNames[index];
		int style=r.nextInt(4);//生成随机样式,0(无样式),1(粗体),2(斜体),3(粗体+斜体)
		int size=r.nextInt(5)+24;//生成随机字号,24~28
		return new Font(fontName,style,size);
	}
	//画干扰线
	private void drawLine(BufferedImage image)
	{
		int num=3;//一共画三条
		Graphics2D g2=(Graphics2D)image.getGraphics();//得到绘制环境
		for(int i=0;i<num;i++)
		{
			int x1=r.nextInt(w);
			int y1=r.nextInt(h);
			int x2=r.nextInt(w);
			int y2=r.nextInt(h);
			g2.setStroke(new BasicStroke(1.5F));
			g2.setColor(Color.blue);
			g2.drawLine(x1, y1, x2, y2);//画线
		}
	}
	//随机生成一个字符
	private char randomChar()
	{
		int index=r.nextInt(code.length());
		//charAt(int index)方法是一个能够用来检索特定索引下的字符的String实例的方法
		return code.charAt(index);
	}
	//创建BufferImage图片缓冲区
	private BufferedImage createImage()
	{
		BufferedImage image=new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
		Graphics2D g2=(Graphics2D)image.getGraphics();
		g2.setColor(this.bgColor);
		g2.fillRect(0, 0, w, h);//填充矩形
		return image;
	}
	//调用这个方法得到验证码
	public BufferedImage getImage()
	{
		BufferedImage image=createImage();//创建图片缓冲区
		Graphics2D g2=(Graphics2D)image.getGraphics();//得到绘制环境
		StringBuilder sb=new StringBuilder();//得到用来装载生成验证码的文本
		//向图片画4个字符
		for(int i=0;i<4;i++)
		{
			String s=randomChar()+"";//随机生成一个字母
			sb.append(s);//把字母添加到sb中去
			float x=i*1.0F*w/4;//设置当前字符的x轴坐标
			g2.setFont(randomFont());//随机设置字体
			g2.setColor(randomColor());//随机设置颜色
			g2.drawString(s,x,h-5);//画图
		}
		this.text=sb.toString();//把生成的字符赋值给this.text
		drawLine(image);//添加干扰线
		return image;//返回
	}
	
	//返回验证码图片的文本
	public String getText()
	{
		return text;
	}
	//保存图片到指定的输出流
	public static void output(BufferedImage image,OutputStream out) throws IOException
	{
		ImageIO.write(image,"JPEG",out);
	}
}

5、在登录页面生成验证码VerifyCodeServlet

package ex01;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * Servlet implementation class VerifyCodeServlet
 * 生成图片
 * 保存图片上的文本到session
 * 把图片响应给客户端
 */
@WebServlet("/VerifyCodeServlet")
public class VerifyCodeServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		VerifyCode vc=new VerifyCode();
		BufferedImage image=vc.getImage();
		request.getSession().setAttribute("session_code",vc.getText());
		//把图片响应给客户端
		VerifyCode.output(image, response.getOutputStream());		
	}
}

6、提交表单之后判断是否登录成功LoginServlet

package ex01;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {	
		/*校验验证码
		 * 1、从session获取正确验证码
		 * 2、从表单获取验证码
		 * 3、进行比较
		 * 4、如果相同,向下运行,负责保存错误信息到request域,转发到login.jsp
		*/
		String sessionCode=(String)request.getSession().getAttribute("session_code");
		String paraCode=(String)request.getParameter("verifyCode");
		if(!paraCode.equalsIgnoreCase(sessionCode))
		{
			request.setAttribute("msg", "验证码错误");
			request.getRequestDispatcher("/session/login.jsp").forward(request, response);
			return;
		}	
		/*
		 * 获取表单数据
		 */
		//处理中文问题
		request.setCharacterEncoding("utf-8");
		//获取
		String username=request.getParameter("username");
		String passwork=request.getParameter("password");
		//校验用户名和密码是否正确
		if(!"kkk".equalsIgnoreCase(username))
		{
			//如果成功的话
			HttpSession session=request.getSession();
			session.setAttribute("username",username);
			response.sendRedirect("/day12/session/succ1.jsp");
		}
		else
		{
			request.setAttribute("msg","您的用户名或密码输入错误");
			request.getRequestDispatcher("/session/login.jsp").forward(request, response);
		}	
	}
}

7、最后是登录成功后显示的页面succ1.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>恭喜您!</h1>
</body>
</html>

最后效果图

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值