一、什么是图片验证码?

可以参考下面这张图:

我们在一些网站登陆的时候,经常需要填写以上图片的信息。

这种图片验证方式是我们最常见的形式,它可以有效的防范恶意攻击者采用恶意工具,来进行窃取用户的密码

接下来将讲正题啦!

1.首先得有一个生成图片验证码的实体类

package com.zhetian.www.util;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random; /**
* @Copyright (C)遮天网络有限公司
* @Author: YUAN HUAI XING
* @qq联系方式: 11234013
* @Date 2020/4/5 18:09
* @Descripthion:
**/ public class ImageVerificationCodeUtil {
private int weight = 100; //验证码图片的长和宽
private int height = 40;
private String text; //用来保存验证码的文本内容
private Random r = new Random(); //获取随机数对象
//private String[] fontNames = {"宋体", "华文楷体", "黑体", "微软雅黑", "楷体_GB2312"}; //字体数组
//字体数组
private String[] fontNames = {"Georgia"};
//验证码数组
private String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ"; /**
* 获取随机的颜色
*
* @return
*/
private Color randomColor() {
int r = this.r.nextInt(225); //这里为什么是225,因为当r,g,b都为255时,即为白色,为了好辨认,需要颜色深一点。
int g = this.r.nextInt(225);
int b = this.r.nextInt(225);
return new Color(r, g, b); //返回一个随机颜色
} /**
* 获取随机字体
*
* @return
*/
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(10) + 24; //随机获取字体的大小
return new Font(fontName, style, size); //返回一个随机的字体
} /**
* 获取随机字符
*
* @return
*/
private char randomChar() {
int index = r.nextInt(codes.length());
return codes.charAt(index);
} /**
* 画干扰线,验证码干扰线用来防止计算机解析图片
*
* @param image
*/
private void drawLine(BufferedImage image) {
int num = r.nextInt(10); //定义干扰线的数量
Graphics2D g = (Graphics2D) image.getGraphics();
for (int i = 0; i < num; i++) {
int x1 = r.nextInt(weight);
int y1 = r.nextInt(height);
int x2 = r.nextInt(weight);
int y2 = r.nextInt(height);
g.setColor(randomColor());
g.drawLine(x1, y1, x2, y2);
}
} /**
* 创建图片的方法
*
* @return
*/
private BufferedImage createImage() {
//创建图片缓冲区
BufferedImage image = new BufferedImage(weight, height, BufferedImage.TYPE_INT_RGB);
//获取画笔
Graphics2D g = (Graphics2D) image.getGraphics();
//设置背景色随机
g.setColor(new Color(255, 255, r.nextInt(245) + 10));
g.fillRect(0, 0, weight, height);
//返回一个图片
return image;
} /**
* 获取验证码图片的方法
*
* @return
*/
public BufferedImage getImage() {
BufferedImage image = createImage();
Graphics2D g = (Graphics2D) image.getGraphics(); //获取画笔
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 4; i++) //画四个字符即可
{
String s = randomChar() + ""; //随机生成字符,因为只有画字符串的方法,没有画字符的方法,所以需要将字符变成字符串再画
sb.append(s); //添加到StringBuilder里面
float x = i * 1.0F * weight / 4; //定义字符的x坐标
g.setFont(randomFont()); //设置字体,随机
g.setColor(randomColor()); //设置颜色,随机
g.drawString(s, x, height - 5);
}
this.text = sb.toString();
drawLine(image);
return image;
} /**
* 获取验证码文本的方法
*
* @return
*/
public String getText() {
return text;
} public static void output(BufferedImage image, OutputStream out) throws IOException //将验证码图片写出的方法
{
ImageIO.write(image, "JPEG", out);
} }

2.在控制器中把图片响应给前端页面(ssm框架)

 /**
* 图片随机码
* @param request
* @param response
* @throws IOException
*/
@RequestMapping("/getVerifiCode")
public void getVerifiCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
/*
1.生成验证码
2.把验证码上的文本存在session中
3.把验证码图片发送给客户端
*/
ImageVerificationCodeUtil ivc = new ImageVerificationCodeUtil(); //用我们的验证码类,生成验证码类对象
BufferedImage image = ivc.getImage(); //获取验证码
String text = ivc.getText(); //获取随机码
HttpSession session = request.getSession();
session.setAttribute("imgcode", text); //将随机码的文本存在session中
System.out.println("文字随机码:"+text);
ImageVerificationCodeUtil.output(image, response.getOutputStream());//将验证码图片响应给客户端
}
3、从session获得验证码字符(ssm框架)
  /**
* 登陆功能:接收用户输入的用户名跟密码(接收参数)
* @param loginUser
* @return
*/
@RequestMapping("/pageData")
@ResponseBody
public Result pageData(LoginUser loginUser,String code,HttpServletRequest request){
HttpSession session = request.getSession();
//获取随机数
String imgcode = (String)session.getAttribute("imgcode");
//调用业务方法
Result<LoginUser> result= loginUserService.loginUserByuserName(loginUser, code,imgcode);
return result;
}
4、业务层(Service)
 /**
* 获取用户输入的用户名与数据库进行对比是否一致
* 如果一致在获取密码对比是否一致
* 都一致再对比图片验证码与用户输入的是否一致
* @param loginUser
* @return
*/
@Override
public Result loginUserByuserName(LoginUser loginUser,String code,String imgcode) {
Result<LoginUser> result = new Result<>();
String userName = loginUser.getUserName();
LoginUser loginUser1 = loginUserDao.loginUserByuserName(userName);
if (code != null && code.equals(imgcode)) {
if (loginUser1 != null) {
String password = loginUser.getPassword();
String password1 = loginUser1.getPassword();
if (password != null && password1 != null && password1.equals(password)) {
result.setCode("0000");
result.setData(loginUser);
return result;
} else {
result.setCode("0001");
result.setMsg("用户名或密码错误!请检查后重新登陆!");
result.setSuccess(false);
return result;
}
} else {
result.setCode("0002");
result.setMsg("用户名不存在!请检查用户名后重新登陆!");
result.setSuccess(false);
return result;
}
}else {
result.setCode("0005");
result.setMsg("验证码不正确!");
result.setSuccess(false);
return result;
} }


5、前端代码
 <div class="form-group">
<%--<label for="password">请输入验证码--%>
</label>
<input id="code" type="text" class="form-control" name="code" width="400px" placeholder="请输入验证码">
<a href="javascript:getVerifiCode()">
<img id="yzm_img" style="cursor:pointer;width: 100px;height: 40px;margin: 0px 0 0 5px;
border-radius: 3px;"
title="点击刷新验证码" src="/login/getVerifiCode" />
</a>
</div>
    function pageData() {
var code=$("#code").val();
var userName=$("#userName").val();
var password=$("#password").val();
var aa = $("input[type='checkbox']").is(":checked");//获取选中状态
if(userName == ''){
alert("请输入用户名。");
return;
}
if(password == ''){
alert("请输入密码。");
return;
}
if(aa==true){
setCookie(); //调用设置Cookie的方法
}else if(aa==false){
setCookie(); //调用设置Cookie的方法
} var params = {
userName:userName,
password:password,
code:code
};
var url = '/login/pageData';
jQuery.ajax({
type: 'POST',
contentType: 'application/x-www-form-urlencoded',
url: url,
data: params,
dataType: 'json',
success: function (data) {
// alert("成功啦");
var code=data.code;
if (code=="0000"){
alert("登陆成功!")
location.href="/tick/list";
} else if(code=="0001"){
alert("登陆提示:"+data.msg);
}else if(code=="0002"){
alert("登陆提示:"+data.msg);
}else if(code=="0005"){
alert("登陆提示:"+data.msg);
}else {
alert("未知异常!");
} },
error: function (data) {
alert("失败啦");
}
});
}


好了,这就是基本上实现的步骤,最后再上几张实现效果图↑↑↑↑↑

@注:本博客仅为个人学习笔记。 所属人:Yuan

JAVA实现图片验证的更多相关文章

  1. 用java写图片

    登录注册的时候都会有图片验证,这是为了防止暴力破解和恶意注册.写一个思路来实现验证图片的实现,只是一个思路,随机生成文字并没有写. import java.awt.Color; import java ...

  2. JavaWeb-SpringSecurity图片验证ImageCode

    系列博文 项目已上传至guthub 传送门 JavaWeb-SpringSecurity初认识 传送门 JavaWeb-SpringSecurity在数据库中查询登陆用户 传送门 JavaWeb-Sp ...

  3. 完整说明使用SpringBoot+js实现滑动图片验证

    常见的网站验证方式有手机短信验证,图片字符验证,滑块验证,滑块图片验证.本文主要讲解的是滑块图片验证的实现流程.包括后台和前端的实现. 实现效果 使用的API java.awt.image.Buffe ...

  4. Java中图片压缩处理

    原文http://cuisuqiang.iteye.com/blog/2045855 整理文档,搜刮出一个Java做图片压缩的代码,稍微整理精简一下做下分享. 首先,要压缩的图片格式不能说动态图片,你 ...

  5. java获取图片原始尺寸

    java获取图片原始尺寸 URL url = null; InputStream is = null; BufferedImage img = null; try { url = new URL(pi ...

  6. 史上最全Java表单验证封装类

    package com.tongrong.utils; import java.util.Collection; import java.util.Map; import java.util.rege ...

  7. Java的登陆验证问题

    java中的登陆验证问题可以有多种方式进行验证,通过拦截器功能完成,可以通过过滤器功能完成,也可以简单的代码在JSP页面中单独完成,其中都 涉及到一个关键的验证步骤,这个验证原理ASP,PHP,JAV ...

  8. java对身份证验证及正则表达式解析

    原文地址:http://www.cnblogs.com/zhongshengzhen/ java对身份证验证及正则表达式解析 package service; import java.text.Par ...

  9. 微信支付java版V3验证数据合法性

    [TOC] 1. 微信支付java版V3验证数据合法性 概要:使用微信支付接口时,微信会返回或回调给商户XML数据,开发者需要验证微信返回的数据是否合法. 特别提醒:商户系统对于支付结果通知的内容一定 ...

随机推荐

  1. Ant-design-pro的动态菜单的实现

    页面效果: 如何实现: 1:分别建立SiderMenu和SubMenu组件 2.去and-desingn-vue的官方文档里copy单文件递归菜单的代码https://www.antdv.com/co ...

  2. python之路-基本数据类型之list列表

    1.概述 列表是python的基本数据类型之一,是一个可变的数据类型,用[]方括号表示,每一项元素使用逗号隔开,可以装大量的数据 #先来看看list列表的源码写了什么,方法:按ctrl+鼠标左键点li ...

  3. Flink系列之状态及检查点

    Flink不同于其他实时计算的框架之处是它可以提供针对不同的状态进行编程和计算.本篇文章的主要思路如下,大家可以选择性阅读. 1. Flink的状态分类及不同点. 2. Flink针对不同的状态进行编 ...

  4. TARS基金会:构建微服务开源生态

    导语 在20世纪60至70年代,软件开发人员通常在大型机和小型机上使用单体架构进行软件开发,没有一个应用程序能够满足大多数最终用户的需求.垂直行业使用的软件代码量更小,与其他应用程序的接口更简单,而可 ...

  5. Linux环境下安装MySQL 5.7.28

    先进入MySQL官网: www.mysql.com 去下载安装包 进入DOWNLOADS选项,点击MySQL Community (GPL) Downloads. 点击进入MySQL Communit ...

  6. 判断括号是否有效(c++描述)

    开门见山,假设我们有一大串的由'{', '}', '[', ']', '(', ')' 这些括号构成比如像这样的"{[}][()"符号串,我们肉眼当然能看出它是非法的,那么如何使用 ...

  7. python 2 和3 的区别

    python 2 和3 的区别 Python2 Python3 打印 print " " print() 输入 raw_input() input() 范围 range/xrang ...

  8. React笔记1

    目录 1.react基础:类组件.函数式组件.ES5/ES6继承 2.生命周期钩子函数 3.什么是JSX 4.props和state有什么区别 5.路由配置 6.自定义封住组件 7.React 状态管 ...

  9. 基于Docker搭建Nginx图片服务器

    前言 一般开发中,都会把图片上传到一个目录,然后将目录和文件名拼接存储在数据库中,但是,这种方法如果没弄好的话可能有一定的缺陷. 若项目搬迁,即时这台服务器本身还在用,存放在服务器的跟项目相关的图片也 ...

  10. 将SublimeText加入右键菜单

    将SublimeText加入右键菜单 Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\*\shell\SublimeText] @=&q ...