JAVA实现图片验证
一、什么是图片验证码?
可以参考下面这张图:

我们在一些网站登陆的时候,经常需要填写以上图片的信息。
这种图片验证方式是我们最常见的形式,它可以有效的防范恶意攻击者采用恶意工具,来进行窃取用户的密码
接下来将讲正题啦!
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实现图片验证的更多相关文章
- 用java写图片
登录注册的时候都会有图片验证,这是为了防止暴力破解和恶意注册.写一个思路来实现验证图片的实现,只是一个思路,随机生成文字并没有写. import java.awt.Color; import java ...
- JavaWeb-SpringSecurity图片验证ImageCode
系列博文 项目已上传至guthub 传送门 JavaWeb-SpringSecurity初认识 传送门 JavaWeb-SpringSecurity在数据库中查询登陆用户 传送门 JavaWeb-Sp ...
- 完整说明使用SpringBoot+js实现滑动图片验证
常见的网站验证方式有手机短信验证,图片字符验证,滑块验证,滑块图片验证.本文主要讲解的是滑块图片验证的实现流程.包括后台和前端的实现. 实现效果 使用的API java.awt.image.Buffe ...
- Java中图片压缩处理
原文http://cuisuqiang.iteye.com/blog/2045855 整理文档,搜刮出一个Java做图片压缩的代码,稍微整理精简一下做下分享. 首先,要压缩的图片格式不能说动态图片,你 ...
- java获取图片原始尺寸
java获取图片原始尺寸 URL url = null; InputStream is = null; BufferedImage img = null; try { url = new URL(pi ...
- 史上最全Java表单验证封装类
package com.tongrong.utils; import java.util.Collection; import java.util.Map; import java.util.rege ...
- Java的登陆验证问题
java中的登陆验证问题可以有多种方式进行验证,通过拦截器功能完成,可以通过过滤器功能完成,也可以简单的代码在JSP页面中单独完成,其中都 涉及到一个关键的验证步骤,这个验证原理ASP,PHP,JAV ...
- java对身份证验证及正则表达式解析
原文地址:http://www.cnblogs.com/zhongshengzhen/ java对身份证验证及正则表达式解析 package service; import java.text.Par ...
- 微信支付java版V3验证数据合法性
[TOC] 1. 微信支付java版V3验证数据合法性 概要:使用微信支付接口时,微信会返回或回调给商户XML数据,开发者需要验证微信返回的数据是否合法. 特别提醒:商户系统对于支付结果通知的内容一定 ...
随机推荐
- js对象中关于this关键字的作用
前两天在前端群看到群友问的一个问题,问题如下: var Name = 'window'; var obj = { Name:'obj字符串', getName:function(){ console. ...
- JZOJ 5328. 【NOIP2017提高A组模拟8.22】世界线
5328. [NOIP2017提高A组模拟8.22]世界线 (File IO): input:worldline.in output:worldline.out Time Limits: 1500 m ...
- Let’s Encrypt https证书安装
我的博客: https://www.seyana.life/post/15 现在已经有很多的免费ssl证书提供商,国内的也有, 不过国内政策要求还要把key给他们, 我们还是用Let's Encryp ...
- 点云3d检测模型pointpillar
PointPillars 一个来自工业界的模型.https://arxiv.org/abs/1812.05784 3D目标检测通常做法 3d卷积 投影到前平面 在bird-view上操作 处理思路依然 ...
- 基于springcloud框架搭建项目-Eureka篇(一)
springcloud项目近年来算是很流行的了,不少公司项目目前都用到了,毕竟优点很多,刚好公司项目用到了,根据自己的理解,简单搭建一下,以便以后学习 这里简单的介绍一下它: SpringCloud, ...
- Community Cloud零基础学习(四)Builder创建自定义的布局
前几篇讲了Community Cloud权限配置等信息,但是没有太讲过 Community如何进行配置layout,本篇主要描述使用Builder去进行符合需求的Community Layout的构建 ...
- MySQL5.7 数据库的my.cnf配置
[client] port socket=/tmp/mysql.sock default-character-set=utf8 [mysql] no-auto-rehash default-chara ...
- Pocket+Evernote 打造个人知识库体系
俗话说巧妇难为无米之炊,还是那个不太恰当的例子. 写作就好比人类的消化系统,想要持续的输出...那么就要持续的输入... 今天就来说一说如何进行持续有效的输入. 信息处理过程 先放一张图,这是我的整个 ...
- isEmpty 判空函数 内部分别判断是 null 空数组 等
import { oneOf, isEmpty } from '@/libs/tools' export const isEmpty = (value) => { if (value == nu ...
- 深入理解Java内存模型(摘)
--摘自 周志明<深入理解Java虚拟机> 转自 https://www.jianshu.com/p/15106e9c4bf3 深入理解Java内存模型(摘) java内存模型(Java ...
