图形验证码登录

news2024/12/23 6:08:53

图形验证码登录

添加图片标签,进入页面访问/api/verifyCode

1.html

<img onclick="javascript:getvCode()" id="verifyimg" style="margin-left: 20px;"/>


<script>
	getvCode();
			/**
			 * 获取验证码
			 * 将验证码写到index.html页面的id = verifyimg 的地方
			 */
			function getvCode() {
				document.getElementById("verifyimg").src = timestamp("/api/verifyCode");
			}
			//为url添加时间戳
			function timestamp(url) {
				var getTimestamp = new Date().getTime();
				if (url.indexOf("?") > -1) {
					url = url + "&timestamp=" + getTimestamp
				} else {
					url = url + "?timestamp=" + getTimestamp
				}
				return url;
			};
</script>

2.Controller

package com.aaa.controller;

import com.aaa.pojo.VerifyCode;
import com.aaa.service.EmployeeImpl.SimpleCharVerifyCodeGenImpl;
import com.aaa.service.IVerifyCodeGen;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Controller
public class verifyCode{

private static final Logger LOGGER = LoggerFactory.getLogger(verifyCode.class);
    String code;
   @ApiOperation(value = "验证码")
   @GetMapping("/verifyCode")
   public void verifyCode(HttpServletRequest request, HttpServletResponse response) {
           IVerifyCodeGen iVerifyCodeGen = new SimpleCharVerifyCodeGenImpl();

        try {
        //设置长宽
        VerifyCode verifyCode = iVerifyCodeGen.generate(80, 28);
        code = verifyCode.getCode();
        LOGGER.info(code);
        //将VerifyCode绑定session
        request.getSession().setAttribute("VerifyCode", code);
        //设置响应头
        response.setHeader("Pragma", "no-cache");
        //设置响应头
        response.setHeader("Cache-Control", "no-cache");
        //在代理服务器端防止缓冲
        response.setDateHeader("Expires", 0);
        //设置响应内容类型
        response.setContentType("image/jpeg");
        response.getOutputStream().write(verifyCode.getImgBytes());
        response.getOutputStream().flush();
        }
        catch (IOException e) {
          LOGGER.info("", e);
           }

   }
}

3.验证码实体类

package com.aaa.pojo;
import lombok.Data;

/**
 * 验证码类
 */
@Data
public class VerifyCode {

    private String code;

    private byte[] imgBytes;

    private long expireTime;

}

4.service

package com.aaa.service;
import com.aaa.pojo.VerifyCode;
import java.io.IOException;
import java.io.OutputStream;
/**
 * 验证码生成接口
 */
public interface IVerifyCodeGen {

    /**
     * 生成验证码并返回code,将图片写的os中
     *
     * @param width
     * @param height
     * @param os
     * @return
     * @throws IOException
     */
    String generate(int width, int height, OutputStream os) throws IOException;

    /**
     * 生成验证码对象
     *
     * @param width
     * @param height
     * @return
     * @throws IOException
     */
    VerifyCode generate(int width, int height) throws IOException;
}

5.serviceImpl

package com.aaa.service.EmployeeImpl;
import com.aaa.pojo.VerifyCode;
import com.aaa.service.IVerifyCodeGen;
import com.aaa.util.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;

/**
 * 验证码实现类
 */
@Service
public class SimpleCharVerifyCodeGenImpl implements IVerifyCodeGen {

    private static final Logger logger = LoggerFactory.getLogger(SimpleCharVerifyCodeGenImpl.class);

    private static final String[] FONT_TYPES = { "\u5b8b\u4f53", "\u65b0\u5b8b\u4f53", "\u9ed1\u4f53", "\u6977\u4f53", "\u96b6\u4e66" };

    private static final int VALICATE_CODE_LENGTH = 4;

    /**
     * 设置背景颜色及大小,干扰线
     *
     * @param graphics
     * @param width
     * @param height
     */
    private static void fillBackground(Graphics graphics, int width, int height) {
        // 填充背景
        graphics.setColor(Color.WHITE);
        //设置矩形坐标x y 为0
        graphics.fillRect(0, 0, width, height);

        // 加入干扰线条
        for (int i = 0; i < 8; i++) {
            //设置随机颜色算法参数
            graphics.setColor(RandomUtils.randomColor(40, 150));
            Random random = new Random();
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int x1 = random.nextInt(width);
            int y1 = random.nextInt(height);
            graphics.drawLine(x, y, x1, y1);
        }
    }

    /**
     * 生成随机字符
     *
     * @param width
     * @param height
     * @param os
     * @return
     * @throws IOException
     */
    @Override
    public String generate(int width, int height, OutputStream os) throws IOException {
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics graphics = image.getGraphics();
        fillBackground(graphics, width, height);
        String randomStr = RandomUtils.randomString(VALICATE_CODE_LENGTH);
        createCharacter(graphics, randomStr);
        graphics.dispose();
        //设置JPEG格式
        ImageIO.write(image, "JPEG", os);
        return randomStr;
    }

    /**
     * 验证码生成
     *
     * @param width
     * @param height
     * @return
     */
    @Override
    public VerifyCode generate(int width, int height) {
        VerifyCode verifyCode = null;
        try {
            //将流的初始化放到这里就不需要手动关闭流
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            String code = generate(width, height, baos);
            verifyCode = new VerifyCode();
            verifyCode.setCode(code);
            verifyCode.setImgBytes(baos.toByteArray());
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
            verifyCode = null;
        }
        return verifyCode;
    }
    /**
     * 设置字符颜色大小
     *
     * @param g
     * @param randomStr
     */
    private void createCharacter(Graphics g, String randomStr) {
        char[] charArray = randomStr.toCharArray();
        for (int i = 0; i < charArray.length; i++) {
            //设置RGB颜色算法参数
            g.setColor(new Color(50 + RandomUtils.nextInt(100),
                    50 + RandomUtils.nextInt(100), 50 + RandomUtils.nextInt(100)));
            //设置字体大小,类型
            g.setFont(new Font(FONT_TYPES[RandomUtils.nextInt(FONT_TYPES.length)], Font.BOLD, 26));
            //设置x y 坐标
            g.drawString(String.valueOf(charArray[i]), 15 * i + 5, 19 + RandomUtils.nextInt(8));
        }
    }
}

6.实现效果

在这里插入图片描述
右侧验证码显示效果,点击图片可以换图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1186069.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Collection集合 迭代器遍历Iterator 和集合增强For

迭代器遍历Iterator 标准写法: 增强For for(类型 名称 : 集合 ) 举例: 不仅可以集合也可以数组 底层仍然是iterator

python自动化测试(十一):写入、读取、修改Excel表格的数据

目录 一、写入 1.1 安装 xlwt 1.2 增加sheet页 1.2.1 新建sheet页 1.2.2 sheet页写入数据 1.2.3 excel保存 1.2.4 完整代码 1.2.5 同一坐标&#xff0c;重复写入 二、读取 2.1 安装读取模块 2.2 读取sheet页 2.2.1 序号读取shee页 2.2.2 通过sheet页的名称读取she…

OpenHarmony 社区运营报告(2023 年 10 月)

● 截至 2023 年 10 月&#xff0c;OpenHarmony 社区共有 51 家共建单位&#xff0c;累计超过 6200 名贡献者产生 24.2 万多个 PR&#xff0c;2.3 万多个 Star&#xff0c;6.1 万多个 Fork&#xff0c;59 个 SIG。 ● OpenHarmony 4.0 版本如期而至&#xff0c;开发套件同步升级…

【React】04.MVC模式和MVVM模式

React是Web前端框架 1、目前市面上比较主流的前端框架 ReactAngular&#xff08;NG框架&#xff09;Vue 主流的思想&#xff1a; 不在直接去操作DOM&#xff0c;而是改为“数据驱动思想” 操作DOM思想&#xff1a; 操作DOM比较消耗性能[主要原因就是&#xff0c;可能会导…

Javascript知识点详解:对象、New命令、Object对象的相关方法

目录 对象 对象是什么 构造函数 new 命令 基本用法 new 命令的原理 new.target Object.create() 创建实例对象 Object 对象的相关方法 Object.getPrototypeOf() Object.setPrototypeOf() Object.create() Object.prototype.isPrototypeOf() Object.prototype.__p…

微信定时发圈,让你轻松管理朋友圈!

有时候我们可能因为工作、生活等原因&#xff0c;错过了最佳的发布朋友圈时间。这时&#xff0c;就可以利用朋友圈的定时发送功能&#xff0c;提前编辑好朋友圈内容&#xff0c;设置好发布时间&#xff0c;让你的好友们在正确的时间看到你的动态。 但是怎么做到朋友圈定时发送…

学C++跟着视频学还是跟着书学?

学C跟着视频学还是跟着书学&#xff1f; 感觉得看基础和目标 如果不是喜欢 C 或者以求职 / 完成 C 相关工作为目标的话&#xff0c;菜鸟教程其实都够了&#xff0c;基本语法掌握就差不多&#xff0c;然后多去写。 最近很多小伙伴找我&#xff0c;说想要一些C的资料&#xff0…

无人机-地面站

借鉴于&#xff1a;https://www.yii666.com/blog/343453.html

网络工程实验记录

网络工程 show ip route show running-config 第一周 相同设备使用交叉线&#xff0c;不同设备之间使用直通线 R1能ping通10.1.1.1 R2能ping通所有的 R3能ping通172.16.1.1 即路由器只能到达自身线连接出去的&#xff0c;另一端就连接不了了。 此时给R1分配静态路由 R…

WebDAV之π-Disk派盘 + GeniusScan

推荐一款功能极其强大的手机微型扫描仪软件,可以将所有的东西扫描成为pdf格式的文档,还支持连接葫芦儿派盘服务。GeniusScan让您的安卓设备变身微型扫描仪。它能让您快速扫描文档,将扫描结果保存JPEG或PDF格式,然后通过电子邮件发送。支持将扫描结果上传到云服务(设备已安装…

第7章 文件读取操作

7.5 用python操作文件的3种模式 读的模式打开只能读&#xff0c;写模式打开只能写。 类似于word的只读模式 所以python打开文件得&#x1f51d;文件 文件打开模式&#xff08;文本模式&#xff09; [DEV (v.v) sa_clusterhybrid01 ~]$ cat test.py f open("name_list…

kubernetes集群编排(7)

目录 k8s认证授权 pod绑定sa 认证 授权 k8s认证授权 pod绑定sa [rootk8s2 ~]# kubectl create sa admin //在当前 Kubernetes 集群中创建一个名为 "admin" 的新服务账户[rootk8s2 secret]# vim pod3.yaml apiVersion: v1 kind: Pod metadata:name: mypod spec…

【机器学习4】降维

常见的降维方法有主成分分析、 线性判别分析、 等距映射、 局部线性嵌入、 拉普拉斯特征映射、 局部保留投影等。 1 PCA最大方差角度理解 PCA无监督学习算法。 PCA的目标&#xff0c; 即最大化投影方差&#xff0c; 也就是让数据在主轴上投影的方差最大。 在黄线所处的轴上&…

Jekyll框架编译GithubPages,提示没有docs

Jekyll Converters::Scss build issue: No such file or directory dir_chdir - /github/workspace/docs Error: No such file or directory dir_chdir - /github/workspace/docs 解决方案&#xff1a; 修改github page仓库中–> 设置—> pages 把里面的\docs&#xf…

【星海出品】flask 与docker

import os from flask import Flask, request from flask import Response, make_response, jsonify import cv2 import base64 import io import uuid from main import eye ​ app Flask(__name__)​ app.route(/, methods[GET, POST]) # 添加路由blend def upload_file():…

2023 全栈工程师 Node.Js 服务器端 web 框架 Express.js 详细教程(更新中)

Express 框架概述 Express 是一个基于 Node.js 平台的快速、开放、极简的Web开发框架。它本身仅仅提供了 web 开发的基础功能&#xff0c;但是通过中间件的方式集成了外部插件来处理HTTP请求&#xff0c;例如 body-parser 用于解析 HTTP 请求体&#xff0c;compression 用于压…

dgl安装教程

我在矩池云服务器上安装了一个dgl的环境&#xff0c;以后都可以用这个了 首先我的基础环境是 最终的版本如下 安装步骤如下 pip install dgl0.9.1 -f https://s3.us-west-2.amazonaws.com/dgl-data/wheels/cu113/repo.html注意不能直接使用 pip install dgl -f https://s…

Nginx网关配置

安装Nginx 下载最新版本Nginx nginx: download 解压 双击nginx.exe启动 浏览器访问 localhost 看到如下界面 微服务准备 准备两个服务&#xff0c;例如&#xff1a;product微服务和order微服务 分别启动后&#xff0c;访问相应服务接口 product服务 http://localhost:9001/…

detectron2环境搭建及自定义coco数据集(voc转coco)训练

detectron2建议ubuntu进行环境搭建&#xff0c;Windows大概率报错 一 环境搭建 创建虚拟环境 conda create -n detectron2 python3.8 -y conda activate detectron2后面下载源代码建议存到git中再git clone git clone https://github.com/facebookresearch/detectron2.git …

王道p40 1.设计一个递归算法,递归删除单链表L中所有值为x的结点(c语言)

视频讲解在这里&#xff1a;&#x1f447; p40 第1题 王道数据结构课后代码题c语言代码实现_哔哩哔哩_bilibili 本题代码如下 void delete(linklist* L,int x)//递归删除x {if((*L)->next! NULL){if ((*L)->next->data x)//找到x{lnode* p (*L)->next;(*L)-&…