Java实现图形验证码

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Point9/article/details/84959875

一、功能分析

在登录页面实现图形验证码的功能

具体实现:(思路分析)

1、登录页面中通过img标签调用封装的工具类VerifyUtil(说明登录页面用jsp实现,为了后期接收响应结果)

2、编写工具类VerifyUtil,具体功能:

  • 生成四个随机字符(数字,大写字母或小写字母)
  • 实例化BufferedImage对象绘制缓存图片,调用对象的getGraphics()方法创建画笔
  • 设置图片背景颜色,确定图片位置和大小
  • 封装getRandomColor()方法,实现字符和干扰线颜色随机
  • 封装getRandomFont()方法,实现字符的字体随机
  • 画随机字符和干扰线
  • 调用ImageIO.write()方法,返回图片给前端

3、前端功能实现:

       通过JavaScript调用VerifyUtil工具类,实现点击图片更换验证码(易错,下面会具体分析)

4、对于验证码的验证,在工具类中存到session中,在在逻辑层实现验证(seeion 中的数据和用户输入的数据对比)

 二、源码实现

1、登录页面 login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户登录</title>
<link href="css/login.css" rel="stylesheet">
<script type="text/javascript">
	function change() {
		var img = document.getElementById("img");
		/* 访问时带参数,避免出现缓存 */
		img.src = "verify?date=" + new Date();
	}
</script>
</head>
<body>
	<div class="login">
		<a href="#" class="choose left">账号登录</a> <span style="color: #e0e0e0">|</span>
		<a href="#" class="choose right">扫码登录</a>
		<%
			//String msg = (String)session.getAttribute("msg");
			String msg = (String) request.getAttribute("msg");
		%>
		<br>
		<%=msg == null ? "" : msg%>
		<form action="login" method="post">
			<input name="uname" type="text" placeholder="用户名" id="login-text">
			<input name="pwd" type="password" placeholder="密码" id="login-pwd">
			<input name="code" type="text" placeholder="验证码" id="login-code">
			<img id="img" src="verify" onclick="change()">
			<input type="submit" value="登录" id="login-sub">
		</form>
		<span class="forget"> <a href="register.jsp">注册账号</a> <span>|</span>
			<a href="forget.jsp">忘记密码?</a></span>
	</div>
</body>
</html>

2、页面的相关样式

/* ----------元素位置布局---------- */
* {
    margin: 0;
    padding: 0;
}
 
.login {
    width: 400px;
    box-shadow: 0 0 15px 3px rgba(51, 51, 51, 0.53);
    margin: 20px auto 0 auto;
    /* border: 1px solid aqua; */
    text-align: center;
}
 
#login-text,
#login-pwd,
#login-img {
    width: 350px;
    height: 30px;
    display: inline-block;
    margin-left: auto;
    margin-right: auto;
}
 
#login-sub {
    width: 364px;
    height: 30px;
    display: inline-block;
    margin-left: auto;
    margin-right: auto;
}
 
/* ----------样式设计---------- */
a {
    color: black;
    text-decoration: none;
}
 
.choose {
    display: inline-block;
    margin-top: 30px;
    font-size: 22px;
}
 
.left {
    color: #f56600;
    margin-right: 15px;
}
 
.right {
    margin-left: 15px;
}
 
#login-text,
#login-pwd {
    padding: 8px 5px;
    font-size: 16px;
    /* box-sizing: border-box; */
    outline: none;;
}
 
#login-text {
    margin-top: 35px;
}
 
#login-pwd {
    margin-top: 15px;
}
 
#login-sub {
    height: 50px;
    margin-top: 15px;
    border: none;
    outline: none;
    font-size: 20px;
    background-color: #f56600;
    color: white;
}
 
.forget {
    display: inline-block;
    margin-top: 15px;
    font-size: 13px;
    color: #e0e0e0;
}
 
.forget a {
    color: #999;
}
 
.forget a:hover {
    text-decoration: underline;
}
 
fieldset {
    display: inline-block;
    width: 364px;
    margin-top: 80px;
    color: #999;
    border: none;
    border-top: 1px solid #999
}
 
#img {
	float: right;
	margin-top: 15px;
	margin-right: 20px;
}

#login-code {
	margin-top: 15px;
	padding: 8px 5px;
	font-size: 16px;
	width: 220px;
	height: 30px;
	display: inline-block;
}

3、工具类VerifyUtil.java

package com.point9.util;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
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;


public class VerifyUtil extends HttpServlet {
	private static final long serialVersionUID = 1L;
    
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req, resp);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 验证码字符集
	    char[] chars = {
	            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
	            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
	            'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
	            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
	            'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
	    // 字符数量
	    int size = 4;
	    // 干扰线数量
	    int lines = 5;
	    // 宽度
	    int width = 110;
	    // 高度
		int height = 50;
	    // 字体大小
	    int font_size = 30;
		//1、创建缓存图片	参数3:图片类型:RGB
		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
		//2、创建画笔,绘制图形
		Graphics graphics = image.getGraphics();
		//3、设置背景颜色
		graphics.setColor(Color.LIGHT_GRAY);//颜色
		//4、绘制背景(此处占用了缓存图片的全部内容)
		graphics.fillRect(0, 0, width, height);
		//5、画随机字符
		Random random = new Random();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < size; i++) {
			//取随机字符索引
			int n = random.nextInt(chars.length);
			//设置随机颜色
			graphics.setColor(getRandomColor());
			//设置随机字体和相关样式
			String font_family = getRandomFont();
			graphics.setFont(new Font(font_family, Font.BOLD, font_size));
			//画字符
			graphics.drawString(chars[n]+"",i * width / size, height * 2 / 3);
			//记录字符
			sb.append(chars[n]);
		}
		
		//把字符存储到session中,便与登录时验证
		req.getSession().setAttribute("code", sb.toString());
		//6、设置干扰线
		for(int i=0;i<lines;i++) {
			// 设置随机颜色
			graphics.setColor(getRandomColor());
            // 随机画线
			graphics.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width), random.nextInt(height));
		}
		//7、返回到前端img中 参数1:缓存图片 参数2:输出格式 参数3:输出流
		try {
			ImageIO.write(image, "jpeg", resp.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
	}
	
	/**
     * 随机取色
     */
    public static Color getRandomColor() {
        Random ran = new Random();
        Color color = new Color(ran.nextInt(256),
                ran.nextInt(256), ran.nextInt(256));
        return color;
    }
    /**
     * 随机字体
     */
    public static String getRandomFont() {
        String[] fonts = new String[] {"微软雅黑","宋体","Serif","Cursive","Fantasy"};
        int i = (int) (Math.random()*(fonts.length));
        String font=fonts[i];
        return font;
    }
}

4、登录验证LoginServlet.java

package com.Point9.servlet;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * Servlet implementation class LoginServlet
 */
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

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

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 1、处理中文乱码问题
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		// 2、获取请求信息
		String uname = request.getParameter("uname");
		String pwd = request.getParameter("pwd");
		String code = request.getParameter("code");
		// 3、处理请求
		String imgCode =(String) request.getSession().getAttribute("code");
		if(!imgCode.equalsIgnoreCase(code)) {//此处忽略大小写
			response.getWriter().write("验证码错误~");
			return;
		}
		/*
		 * 遍历集合,如果信息匹配则登录成功
         * 此处自行更改,验证用户名和密码是否正确
		 */
		List<Student> list = DBCenter.list;
		boolean flag = false;
		for (Student st : list) {
			if (st.getUname().equals(uname)&&st.getPwd().equals(pwd)) {
				flag = true;
				break;
			}
		}
		// 4、响应处理结果
		if(flag) {
			response.getWriter().write("登录成功!");
		}else {
			request.setAttribute("msg", "request+请求转发:登录失败!");
			request.getRequestDispatcher("login.jsp").forward(request, response);
		}
	}
}

写在最后,此处是忽略大小写的(equalsIgnoreCase)!

"A".equalsIgnoreCase("a");比较时直接忽略大小写

str.toLowerCase()转小写,str.toUpperCase()转大写

本博客的全部源码,我已经放Git上了,供大家交流学习。https://gitee.com/point9/verify_util

最后福利到,欢迎有兴趣的朋友一起交流成长。


Web全栈技术交流

点击链接加入群聊【Web全栈交流群】:https://jq.qq.com/?_wv=1027&k=5rnUzsF

QQ群二维码

猜你喜欢

转载自blog.csdn.net/Point9/article/details/84959875