最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot+Vue3實現(xiàn)登錄驗證碼功能教程

 更新時間:2026年04月24日 08:31:58   作者:心態(tài)還需努力呀  
本文介紹了驗證碼的生成和展示過程,后端使用Java生成驗證碼圖片并保存到Redis,前端使用Vue展示圖片并點擊刷新驗證碼,具體步驟包括生成驗證碼工具類、編寫Controller接口、前端編寫圖片展示代碼和事件綁定,最后在登錄時驗證前端輸入的驗證碼是否與后端保存的一致

前言

登錄頁面都會有輸入用戶名、密碼和驗證碼而判斷用戶是否登錄成功做出響應(yīng)的操作。輸入用戶名和密碼提交表單做登錄驗證這個相信看到這篇文章的小伙伴們都是小問題(熟練地不能在熟練了)。但這個驗證碼用戶點擊刷新驗證碼,用戶填寫后才能正常登錄。隨機生成圖片驗證碼就會有些疑惑,不知道該怎么做。

這篇文章我們就來重點看如何生成驗證碼,前端如何展示,如何點擊驗證碼后會換張圖片(就是常見到的“看不清?換一張圖”)這一功能。

做出下圖的驗證碼:

一、導(dǎo)入生成驗證碼工具類

下面就是生成驗證碼圖片的工具類,里面的參數(shù)都有注釋,大家可以按照自己喜歡的樣式調(diào)節(jié)驗證碼的參數(shù)(隨機生成的數(shù)量、背景顏色、干擾線等)。

package com.medical.study.utils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;

public class VerifyCode {
    //寬和高
    private int w = 85;
    private int h = 40;

    private Random r = new Random();
    // 定義有那些字體
    private String[] fontNames = { "宋體", "華文楷體", "黑體", "微軟雅黑", "楷體_GB2312" };
    // 定義有那些驗證碼的隨機字符
    private String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ";
    // 生成背景色
    private Color bgColor = new Color(0, 255, 255);
    // 用于gettext 方法 獲得生成的驗證碼文本
    private String text;

    // 生成隨機顏色
    private Color randomColor() {
        int red = r.nextInt(255);
        int green = r.nextInt(255);
        int blue = r.nextInt(255);
        return new Color(red, green, blue);
    }

    // 生成隨機字體
    private Font randomFont() {
        int index = r.nextInt(fontNames.length);
        String fontName = fontNames[index];
        int style = r.nextInt(4);
        int size = r.nextInt(5) + 24;

        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.white);
            g2.drawLine(x1, y1, x2, y2);
        }
    }

    // 得到codes的長度內(nèi)的隨機數(shù) 并使用charAt 取得隨機數(shù)位置上的codes中的字符
    private char randomChar() {
        int index = r.nextInt(codes.length());
        return codes.charAt(index);
    }

    // 創(chuàng)建一張驗證碼的圖片
    public BufferedImage createImage() {
        BufferedImage image = new BufferedImage(w, h,
                BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = (Graphics2D) image.getGraphics();
        StringBuilder sb = new StringBuilder();
        // 向圖中畫四個字符
        for (int i = 0; i < 4; i++) {
            String s = randomChar() + "";
            sb.append(s);
            float x = i * 1.0F * w / 4;
            g2.setFont(randomFont());
            g2.setColor(randomColor());
            g2.drawString(s, x, h - 5);

        }
        this.text = sb.toString();
        drawLine(image);


        // 返回圖片
        return image;

    }

    // 得到驗證碼的文本 后面是用來和用戶輸入的驗證碼 檢測用
    public String getText() {
        return text;
    }

    // 定義輸出的對象和輸出的方向
    public static void output(BufferedImage bi, OutputStream fos)
            throws FileNotFoundException, IOException {
        ImageIO.write(bi, "JPEG", fos);
    }

}

二、編寫Controller生成驗證碼的接口

1.這里我的接口是:localhost:8081/code/verify。

2.將生成的驗證碼保存,這里我保存到了redis中,你也可以保存到其他的地方(session),在登錄驗證時能取到這里保存的值即可。

3.@CrossOrigin是跨域請求,因為我前端是8080端口,后端是8081端口。

代碼如下:

package com.medical.study.controller;

import com.medical.study.utils.VerifyCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * 隨機4位數(shù)的驗證碼
 */

@RestController
@CrossOrigin
@RequestMapping("/code")
public class VerifyController {

    @Autowired
    private RedisTemplate redisTemplate;

    @RequestMapping("/verify")
    public void Verify(HttpServletRequest request, HttpServletResponse response) throws IOException {
                VerifyCode code = new VerifyCode();
        BufferedImage image = code.createImage();

        //驗證碼
        System.err.println(code.getText());

        //保存驗證碼到Redis,一分鐘有效期
        redisTemplate.opsForValue().set("verify:"+code.getText(),code.getText(),1L, TimeUnit.MINUTES);

        //驗證碼圖片格式
        ImageIO.write(image,"jpg",response.getOutputStream());


    }


}

三、前端代碼編寫

3.1 img標(biāo)簽

1.綁定事件,點擊后更換驗證碼圖片

2.v-model綁定src屬性

<img :src="verifySrc" alt="圖片無法加載" @click="changeVerify()" >

3.2 vue代碼

1.常量verifySrc就和上面src的屬性綁定。值是后端的接口。

2.方法是上面img標(biāo)簽綁定的事件,點擊后需要重新發(fā)送請求。

這里為什么要加new Date().getTime()表示當(dāng)前時間毫秒值呢?

答:首先瀏覽器中存在緩存,請求時緩存是先看請求地址是不是一樣,地址一樣就取出緩存內(nèi)容。所以不加的話就會直接取緩存的值,所以圖片點擊就會沒有任何反映。

加new Date().getTime(),每次請求地址就不一樣。保證了不從緩存里面取。就會去重新調(diào)用接口返回不一樣的驗證碼圖片。

//驗證碼
	const verifySrc=ref("http://localhost:8081/code/verify");
	function changeVerify(){
		verifySrc.value="http://localhost:8081/code/verify?"+new Date().getTime()
		
	}

四、效果圖

點擊圖片也是可以更換驗證碼圖片的。這里就不給大家演示了,感興趣可以自己編寫嘗試嘗試。

如下圖所示:

五、補充后端驗證

1.在提交表單時發(fā)送post將數(shù)據(jù)和用戶輸入的驗證碼傳給后端。

2.controller層login接口編寫邏輯代碼

首先判斷存儲的驗證碼和用戶輸入的是否一致。

  • 2.1 如果不一致直接返回錯誤信息。如“驗證碼輸入錯誤”。
  • 2.2 如果一致的話執(zhí)行登錄的邏輯,查詢數(shù)據(jù)庫查看用戶名、密碼。

這個就和以前的寫法一樣了。這里就不給大家展示代碼了。相信大家能夠獨立完成。

總結(jié)

登錄頁面的驗證碼編寫從后端生成驗證碼圖片到前端將圖片展示到頁面的流程和代碼都編寫完了。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • springcloud整合gateway實現(xiàn)網(wǎng)關(guān)全局過濾器功能

    springcloud整合gateway實現(xiàn)網(wǎng)關(guān)全局過濾器功能

    本文主要介紹了springcloud整合gateway實現(xiàn)網(wǎng)關(guān)全局過濾器功能,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • mybatis 為什么千萬不要使用 where 1=1

    mybatis 為什么千萬不要使用 where 1=1

    這篇文章主要介紹了mybatis 為什么千萬不要使用 where 1=1,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • 深入淺出分析Java抽象類和接口【功能,定義,用法,區(qū)別】

    深入淺出分析Java抽象類和接口【功能,定義,用法,區(qū)別】

    這篇文章主要介紹了Java抽象類和接口,結(jié)合實例形式深入淺出的分析了java抽象類與接口的功能功能,定義,用法及區(qū)別,需要的朋友可以參考下
    2017-08-08
  • Java后端配置允許跨域方式

    Java后端配置允許跨域方式

    本文介紹了在不同技術(shù)和框架中配置跨域資源共享(CORS)的方法,包括使用SpringMVC的@CrossOrigin注解、SpringBoot的全局CORS配置、SpringSecurity中的CORS集成以及手動設(shè)置響應(yīng)頭,根據(jù)具體需求和技術(shù)棧,選擇合適的方法來確??缬蛘埱蟮陌踩院陀行?/div> 2025-02-02
  • Java實現(xiàn)讀取及生成Excel文件的方法

    Java實現(xiàn)讀取及生成Excel文件的方法

    這篇文章主要介紹了Java實現(xiàn)讀取及生成Excel文件的方法,結(jié)合實例形式分析了java通過引入第三方j(luò)ar包poi-3.0.1-FINAL-20070705.jar實現(xiàn)針對Excel文件的讀取及生成功能,需要的朋友可以參考下
    2017-12-12
  • Java內(nèi)部類詳解

    Java內(nèi)部類詳解

    內(nèi)部類在 Java 里面算是非常常見的一個功能了,在日常開發(fā)中我們肯定多多少少都用過,這里總結(jié)一下關(guān)于 Java 中內(nèi)部類的相關(guān)知識點和一些使用內(nèi)部類時需要注意的點。
    2020-02-02
  • 對HttpServletRequest中的Header進行增刪實現(xiàn)過程

    對HttpServletRequest中的Header進行增刪實現(xiàn)過程

    文章介紹了如何通過反射來修改和刪除HttpServletRequest中的Header,以實現(xiàn)對外部請求數(shù)據(jù)的自定義處理,通過示例代碼和分析,展示了如何在Tomcat和Undertow容器中實現(xiàn)這一功能
    2025-12-12
  • Java面向?qū)ο笕馕鲋畉his關(guān)鍵字+構(gòu)造方法+標(biāo)準(zhǔn)JavaBean

    Java面向?qū)ο笕馕鲋畉his關(guān)鍵字+構(gòu)造方法+標(biāo)準(zhǔn)JavaBean

    本文介紹了Java面向?qū)ο蟮母呒墐?nèi)容,包括無參構(gòu)造方法和帶參構(gòu)造方法,標(biāo)準(zhǔn)JavaBean類是企業(yè)開發(fā)中用于封裝數(shù)據(jù)的規(guī)范類,必須遵循特定的命名和方法規(guī)范,通過本文學(xué)習(xí),讀者可以掌握這些關(guān)鍵概念并應(yīng)用到實際開發(fā)中,感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • Java多線程并發(fā)Unsafe與CAS的用法解讀

    Java多線程并發(fā)Unsafe與CAS的用法解讀

    這篇文章主要介紹了Java多線程并發(fā)Unsafe與CAS的用法,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-05-05
  • 手把手帶你了解Java-Stream流方法學(xué)習(xí)及總結(jié)

    手把手帶你了解Java-Stream流方法學(xué)習(xí)及總結(jié)

    這篇文章主要介紹了通過實例了解JavaStream流的方法學(xué)習(xí)和總結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2021-08-08

最新評論

大连市| 吉首市| 邳州市| 苏尼特右旗| 江永县| 乌鲁木齐县| 上林县| 方城县| 井陉县| 水富县| 定陶县| 龙陵县| 城市| 安义县| 肃北| 舞钢市| 蓝田县| 内丘县| 山东省| 南乐县| 长垣县| 云和县| 独山县| 洛川县| 临泽县| 西藏| 石景山区| 民县| 夏津县| 汶上县| 灵璧县| 宝丰县| 卫辉市| 张家口市| 静乐县| 安顺市| 万年县| 石首市| 长汀县| 吴堡县| 宁安市|