欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java實(shí)現(xiàn)動(dòng)態(tài)驗(yàn)證碼生成

 更新時(shí)間:2022年04月22日 08:23:52   作者:Keson Z  
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)動(dòng)態(tài)驗(yàn)證碼生成,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了Java動(dòng)態(tài)驗(yàn)證碼生成的具體代碼,供大家參考,具體內(nèi)容如下

說明:今天給大家來帶來一個(gè)自動(dòng)生成驗(yàn)證碼的處理方法。驗(yàn)證碼的出現(xiàn)有效減少了注入灌水以及破解密碼等惡意操作,提高了系統(tǒng)運(yùn)行的流暢性,保護(hù)了系統(tǒng)用戶的隱私安全,具體實(shí)現(xiàn)方法如下:

1.首先我們先編寫一個(gè)專門的驗(yàn)證碼生成工具類,該工具類代碼如下:

package com.ordering.util;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.Random;

/**
?* 驗(yàn)證碼生成器
?* @author 諾坎普10號(hào)
?* @date 2020-2-25
?*/
public class CpachaUtil {
?? ?
?? ?/**
?? ? * 驗(yàn)證碼來源
?? ? */
?? ?final private char[] code = {
?? ??? ?'2', '3', '4', '5', '6', '7', '8', '9',
?? ??? ?'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
?? ??? ?'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v',?
?? ??? ?'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F',
?? ??? ?'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R',
?? ??? ?'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
?? ?};
?? ?/**
?? ? * 字體
?? ? */
?? ?final private String[] fontNames = new String[]{
?? ??? ??? ?"黑體", "宋體", "Courier", "Arial",?
?? ??? ??? ?"Verdana", "Times", "Tahoma", "Georgia"};
?? ?/**
?? ? * 字體樣式
?? ? */
?? ?final private int[] fontStyles = new int[]{
?? ??? ??? ?Font.BOLD, Font.ITALIC|Font.BOLD
?? ?};
?? ?
?? ?/**
?? ? * 驗(yàn)證碼長度
?? ? * 默認(rèn)4個(gè)字符
?? ? */
?? ?private int vcodeLen = 4;
?? ?/**
?? ? * 驗(yàn)證碼圖片字體大小
?? ? * 默認(rèn)17
?? ? */
?? ?private int fontsize = 21;
?? ?/**
?? ? * 驗(yàn)證碼圖片寬度
?? ? */
?? ?private int width = (fontsize+1)*vcodeLen+10;
?? ?/**
?? ? * 驗(yàn)證碼圖片高度
?? ? */
?? ?private int height = fontsize+12;
?? ?/**
?? ? * 干擾線條數(shù)
?? ? * 默認(rèn)3條
?? ? */
?? ?private int disturbline = 3;
?? ?
?? ?
?? ?public CpachaUtil(){}
?? ?
?? ?/**
?? ? * 指定驗(yàn)證碼長度
?? ? * @param vcodeLen 驗(yàn)證碼長度
?? ? */
?? ?public CpachaUtil(int vcodeLen) {
?? ??? ?this.vcodeLen = vcodeLen;
?? ??? ?this.width = (fontsize+1)*vcodeLen+10;
?? ?}
?? ?
?? ?/**
?? ? * 指定驗(yàn)證碼長度、圖片寬度、高度
?? ? * @param vcodeLen
?? ? * @param width
?? ? * @param height
?? ? */
?? ?public CpachaUtil(int vcodeLen,int width,int height) {
?? ??? ?this.vcodeLen = vcodeLen;
?? ??? ?this.width = width;
?? ??? ?this.height = height;
?? ?}
?? ?
?? ?/**
?? ? * 生成驗(yàn)證碼圖片
?? ? * @param vcode 要畫的驗(yàn)證碼
?? ? * @param drawline 是否畫干擾線
?? ? * @return
?? ? */
?? ?public BufferedImage generatorVCodeImage(String vcode, boolean drawline){
?? ??? ?//創(chuàng)建驗(yàn)證碼圖片
?? ??? ?BufferedImage vcodeImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
?? ??? ?Graphics g = vcodeImage.getGraphics();
?? ??? ?//填充背景色
?? ??? ?g.setColor(new Color(246, 240, 250));
?? ??? ?g.fillRect(0, 0, width, height);
?? ??? ?if(drawline){
?? ??? ??? ?drawDisturbLine(g);
?? ??? ?}
?? ??? ?//用于生成偽隨機(jī)數(shù)
?? ??? ?Random ran = new Random();
?? ??? ?//在圖片上畫驗(yàn)證碼
?? ??? ?for(int i = 0;i < vcode.length();i++){
?? ??? ??? ?//設(shè)置字體
?? ??? ??? ?g.setFont(new Font(fontNames[ran.nextInt(fontNames.length)], fontStyles[ran.nextInt(fontStyles.length)], fontsize));
?? ??? ??? ?//隨機(jī)生成顏色
?? ??? ??? ?g.setColor(getRandomColor());
?? ??? ??? ?//畫驗(yàn)證碼
?? ??? ??? ?g.drawString(vcode.charAt(i)+"", i*fontsize+10, fontsize+5);
?? ??? ?}
?? ??? ?//釋放此圖形的上下文以及它使用的所有系統(tǒng)資源
?? ??? ?g.dispose();
?? ??? ?
?? ??? ?return vcodeImage;
?? ?}
?? ?/**
?? ? * 獲得旋轉(zhuǎn)字體的驗(yàn)證碼圖片
?? ? * @param vcode
?? ? * @param drawline 是否畫干擾線
?? ? * @return
?? ? */
?? ?public BufferedImage generatorRotateVCodeImage(String vcode, boolean drawline){
?? ??? ?//創(chuàng)建驗(yàn)證碼圖片
?? ??? ?BufferedImage rotateVcodeImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
?? ??? ?Graphics2D g2d = rotateVcodeImage.createGraphics();
?? ??? ?//填充背景色
?? ??? ?g2d.setColor(new Color(246, 240, 250));
?? ??? ?g2d.fillRect(0, 0, width, height);
?? ??? ?if(drawline){
?? ??? ??? ?drawDisturbLine(g2d);
?? ??? ?}
?? ??? ?//在圖片上畫驗(yàn)證碼
?? ??? ?for(int i = 0;i < vcode.length();i++){
?? ??? ??? ?BufferedImage rotateImage = getRotateImage(vcode.charAt(i));
?? ??? ??? ?g2d.drawImage(rotateImage, null, (int) (this.height * 0.7) * i, 0);
?? ??? ?}
?? ??? ?g2d.dispose();
?? ??? ?return rotateVcodeImage;
?? ?}
?? ?/**
?? ? * 生成驗(yàn)證碼
?? ? * @return 驗(yàn)證碼
?? ? */
?? ?public String generatorVCode(){
?? ??? ?int len = code.length;
?? ??? ?Random ran = new Random();
?? ??? ?StringBuffer sb = new StringBuffer();
?? ??? ?for(int i = 0;i < vcodeLen;i++){
?? ??? ??? ?int index = ran.nextInt(len);
?? ??? ??? ?sb.append(code[index]);
?? ??? ?}
?? ??? ?return sb.toString();
?? ?}
?? ?/**
?? ? * 為驗(yàn)證碼圖片畫一些干擾線
?? ? * @param g?
?? ? */
?? ?private void drawDisturbLine(Graphics g){
?? ??? ?Random ran = new Random();
?? ??? ?for(int i = 0;i < disturbline;i++){
?? ??? ??? ?int x1 = ran.nextInt(width);
?? ??? ??? ?int y1 = ran.nextInt(height);
?? ??? ??? ?int x2 = ran.nextInt(width);
?? ??? ??? ?int y2 = ran.nextInt(height);
?? ??? ??? ?g.setColor(getRandomColor());
?? ??? ??? ?//畫干擾線
?? ??? ??? ?g.drawLine(x1, y1, x2, y2);
?? ??? ?}
?? ?}
?? ?/**
?? ? * 獲取一張旋轉(zhuǎn)的圖片
?? ? * @param c 要畫的字符
?? ? * @return
?? ? */
?? ?private BufferedImage getRotateImage(char c){
?? ??? ?BufferedImage rotateImage = new BufferedImage(height, height, BufferedImage.TYPE_INT_ARGB);
?? ??? ?Graphics2D g2d = rotateImage.createGraphics();
?? ??? ?//設(shè)置透明度為0
?? ??? ?g2d.setColor(new Color(255, 255, 255, 0));
?? ??? ?g2d.fillRect(0, 0, height, height);
?? ??? ?Random ran = new Random();
?? ??? ?g2d.setFont(new Font(fontNames[ran.nextInt(fontNames.length)], fontStyles[ran.nextInt(fontStyles.length)], fontsize));
?? ??? ?g2d.setColor(getRandomColor());
?? ??? ?double theta = getTheta();
?? ??? ?//旋轉(zhuǎn)圖片
?? ??? ?g2d.rotate(theta, height/2, height/2);
?? ??? ?g2d.drawString(Character.toString(c), (height-fontsize)/2, fontsize+5);
?? ??? ?g2d.dispose();
?? ??? ?
?? ??? ?return rotateImage;
?? ?}
?? ?/**
?? ? * @return 返回一個(gè)隨機(jī)顏色
?? ? */
?? ?private Color getRandomColor(){
?? ??? ?Random ran = new Random();
?? ??? ?return new Color(ran.nextInt(220), ran.nextInt(220), ran.nextInt(220));?
?? ?}
?? ?/**
?? ? * @return 角度
?? ? */
?? ?private double getTheta(){
?? ??? ?return ((int) (Math.random()*1000) % 2 == 0 ? -1 : 1)*Math.random();
?? ?}

?? ?/**
?? ? * @return 驗(yàn)證碼字符個(gè)數(shù)
?? ? */
?? ?public int getVcodeLen() {
?? ??? ?return vcodeLen;
?? ?}
?? ?/**
?? ? * 設(shè)置驗(yàn)證碼字符個(gè)數(shù)
?? ? * @param vcodeLen
?? ? */
?? ?public void setVcodeLen(int vcodeLen) {
?? ??? ?this.width = (fontsize+3)*vcodeLen+10;
?? ??? ?this.vcodeLen = vcodeLen;
?? ?}
?? ?/**
?? ? * @return 字體大小
?? ? */
?? ?public int getFontsize() {
?? ??? ?return fontsize;
?? ?}
?? ?/**
?? ? * 設(shè)置字體大小
?? ? * @param fontsize
?? ? */
?? ?public void setFontsize(int fontsize) {
?? ??? ?this.width = (fontsize+3)*vcodeLen+10;
?? ??? ?this.height = fontsize+15;
?? ??? ?this.fontsize = fontsize;
?? ?}
?? ?/**
?? ? * @return 圖片寬度
?? ? */
?? ?public int getWidth() {
?? ??? ?return width;
?? ?}
?? ?/**
?? ? * 設(shè)置圖片寬度
?? ? * @param width
?? ? */
?? ?public void setWidth(int width) {
?? ??? ?this.width = width;
?? ?}
?? ?/**
?? ? * @return 圖片高度
?? ? */
?? ?public int getHeight() {
?? ??? ?return height;
?? ?}
?? ?/**
?? ? * 設(shè)置圖片高度
?? ? * @param height?
?? ? */
?? ?public void setHeight(int height) {
?? ??? ?this.height = height;
?? ?}
?? ?/**
?? ? * @return 干擾線條數(shù)
?? ? */
?? ?public int getDisturbline() {
?? ??? ?return disturbline;
?? ?}
?? ?/**
?? ? * 設(shè)置干擾線條數(shù)
?? ? * @param disturbline
?? ? */
?? ?public void setDisturbline(int disturbline) {
?? ??? ?this.disturbline = disturbline;
?? ?}
?? ?
}

2.然后在頁面端定義一個(gè)顯示驗(yàn)證碼的控件,再寫一個(gè)js函數(shù)來對(duì)后臺(tái)動(dòng)態(tài)生成驗(yàn)證碼方法進(jìn)行調(diào)用,主要代碼如下:

<div class="login-center-input-text">驗(yàn)證碼</div>
<img id="cpacha-img" title="點(diǎn)擊切換驗(yàn)證碼" style="cursor:pointer;" src="get_cpacha?vl=4&w=150&h=40&type=loginCpacha" width="110px" height="30px" onclick="changeCpacha()">
</div>

<script type="text/javascript">
function changeCpacha(){
?? ??? ?$("#cpacha-img").attr("src",'get_cpacha?vl=4&w=150&h=40&type=loginCpacha&t=' + new Date().getTime());
?? ?}
</script>

3.控制器中代碼如下:

/**
?? ? * 本系統(tǒng)所有的驗(yàn)證碼均采用此方法
?? ? *?
?? ? * @param vcodeLen
?? ? * @param width
?? ? * @param height
?? ? * @param cpachaType:用來區(qū)別驗(yàn)證碼的類型,傳入字符串
?? ? * @param request
?? ? * @param response
?? ? */
?? ?@RequestMapping(value = "/get_cpacha", method = RequestMethod.GET)
?? ?public void generateCpacha(@RequestParam(name = "vl", required = false, defaultValue = "4") Integer vcodeLen,
?? ??? ??? ?@RequestParam(name = "w", required = false, defaultValue = "100") Integer width,
?? ??? ??? ?@RequestParam(name = "h", required = false, defaultValue = "30") Integer height,
?? ??? ??? ?@RequestParam(name = "type", required = true, defaultValue = "loginCpacha") String cpachaType,
?? ??? ??? ?HttpServletRequest request, HttpServletResponse response) {
?? ??? ?//根據(jù)頁面?zhèn)魅氲尿?yàn)證碼長度、圖片寬度以及圖片長度來實(shí)例化驗(yàn)證碼實(shí)體
?? ??? ?CpachaUtil cpachaUtil = new CpachaUtil(vcodeLen, width, height);
?? ??? ?//生成驗(yàn)證碼
?? ??? ?String generatorVCode = cpachaUtil.generatorVCode();
?? ??? ?//把驗(yàn)證碼存入session
?? ??? ?request.getSession().setAttribute(cpachaType, generatorVCode);
?? ??? ?//根據(jù)驗(yàn)證碼生成相應(yīng)的驗(yàn)證碼圖片
?? ??? ?BufferedImage generatorRotateVCodeImage = cpachaUtil.generatorRotateVCodeImage(generatorVCode, true);
?? ??? ?try {
?? ??? ??? ?ImageIO.write(generatorRotateVCodeImage, "gif", response.getOutputStream());
?? ??? ?} catch (IOException e) {
?? ??? ??? ?// TODO Auto-generated catch block
?? ??? ??? ?e.printStackTrace();
?? ??? ?}
?? ?}

4.實(shí)現(xiàn)效果如下圖所示:

5.控制器驗(yàn)證碼驗(yàn)證部分如下圖所示:

//若驗(yàn)證碼為空
if (StringUtils.isEmpty(cpacha)) {
?? ??? ??? ?ret.put("type", "error");
?? ??? ??? ?ret.put("msg", "請(qǐng)?zhí)顚戲?yàn)證碼!");
?? ??? ??? ?return ret;
?? ??? ?}
?? ??? ?//獲取保存在session中的登錄驗(yàn)證碼對(duì)象
?? ??? ?Object loginCpacha = request.getSession().getAttribute("loginCpacha");
?? ??? ?//若登錄驗(yàn)證碼實(shí)體對(duì)象為空
?? ??? ?if (loginCpacha == null) {
?? ??? ??? ?ret.put("type", "error");
?? ??? ??? ?ret.put("msg", "會(huì)話超時(shí),請(qǐng)刷新頁面!");
?? ??? ??? ?return ret;
?? ??? ?}
?? ??? ?//若輸入的驗(yàn)證碼轉(zhuǎn)化成大寫之后不等于轉(zhuǎn)換成大寫的session中保存的驗(yàn)證碼
?? ??? ?if (!cpacha.toUpperCase().equals(loginCpacha.toString().toUpperCase())) {
?? ??? ??? ?ret.put("type", "error");
?? ??? ??? ?ret.put("msg", "驗(yàn)證碼錯(cuò)誤!");
?? ??? ??? ?//實(shí)例化日志信息實(shí)體
?? ??? ??? ?OrderingLog orderingLog = new OrderingLog("用戶名為" + user.getOuUsername() + "的用戶登錄時(shí)輸入驗(yàn)證碼錯(cuò)誤!", new Date());
?? ??? ??? ?//添加日志信息
?? ??? ??? ?logService.addLog(orderingLog);
?? ??? ??? ?return ret;
?? ??? ?}

注意:

只有當(dāng)你把當(dāng)前系統(tǒng)時(shí)間傳入該驗(yàn)證碼生成工具類中,才能實(shí)現(xiàn)點(diǎn)擊驗(yàn)證碼圖片,實(shí)時(shí)自動(dòng)替換驗(yàn)證碼,如下圖所示:

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Mybatis防止sql注入的實(shí)例

    Mybatis防止sql注入的實(shí)例

    本文通過實(shí)例給大家介紹了Mybatis防止sql注入的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-06-06
  • Spring?Boot中優(yōu)雅地處理參數(shù)傳遞的技巧分享

    Spring?Boot中優(yōu)雅地處理參數(shù)傳遞的技巧分享

    最近一直在學(xué)習(xí)Spring Boot,今天將其中的從前臺(tái)過來的參數(shù)傳遞總結(jié)一下,下面這篇文章主要給大家介紹了關(guān)于Spring?Boot中優(yōu)雅地處理參數(shù)傳遞的技巧,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • java集合類arraylist循環(huán)中刪除特定元素的方法

    java集合類arraylist循環(huán)中刪除特定元素的方法

    下面小編就為大家?guī)硪黄狫ava集合類ArrayList循環(huán)中刪除特定元素的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-11-11
  • 后端如何接收格式為x-www-form-urlencoded的數(shù)據(jù)

    后端如何接收格式為x-www-form-urlencoded的數(shù)據(jù)

    x-www-form-urlencoded格式是一種常見的HTTP請(qǐng)求數(shù)據(jù)格式,它將請(qǐng)求參數(shù)編碼為鍵值對(duì)的形式,以便于傳輸和解析,下面這篇文章主要給大家介紹了關(guān)于后端如何接收格式為x-www-form-urlencoded的數(shù)據(jù),需要的朋友可以參考下
    2023-05-05
  • Java static方法用法實(shí)戰(zhàn)案例總結(jié)

    Java static方法用法實(shí)戰(zhàn)案例總結(jié)

    這篇文章主要介紹了Java static方法用法,結(jié)合具體案例形式總結(jié)分析了java static方法功能、使用方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2019-09-09
  • 關(guān)于Mybatis-plus設(shè)置字段為空的正確寫法

    關(guān)于Mybatis-plus設(shè)置字段為空的正確寫法

    這篇文章主要介紹了關(guān)于Mybatis-plus設(shè)置字段為空的正確寫法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • idea中使用Inputstream流導(dǎo)致中文亂碼解決方法

    idea中使用Inputstream流導(dǎo)致中文亂碼解決方法

    很多朋友遇到一個(gè)措手不及的問題當(dāng)idea中使用Inputstream流導(dǎo)致中文亂碼及Java FileInputStream讀中文亂碼問題,針對(duì)這兩個(gè)問題很多朋友不知道該如何解決,下面小編把解決方案分享給大家供大家參考
    2021-05-05
  • Java連接合并2個(gè)數(shù)組(Array)的5種方法例子

    Java連接合并2個(gè)數(shù)組(Array)的5種方法例子

    最近在寫代碼時(shí)遇到了需要合并兩個(gè)數(shù)組的需求,突然發(fā)現(xiàn)以前沒用過,于是研究了一下合并數(shù)組的方式,這篇文章主要給大家介紹了關(guān)于Java連接合并2個(gè)數(shù)組(Array)的5種方法,需要的朋友可以參考下
    2023-12-12
  • java 將一個(gè)數(shù)組逆序輸出的方法

    java 將一個(gè)數(shù)組逆序輸出的方法

    今天小編就為大家分享一篇java 將一個(gè)數(shù)組逆序輸出的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-06-06
  • SpringBoot 定時(shí)任務(wù)遇到的坑

    SpringBoot 定時(shí)任務(wù)遇到的坑

    這篇文章主要介紹了SpringBoot 定時(shí)任務(wù)遇到的坑,今天踩的這個(gè)坑和 cron 表達(dá)式有關(guān),文中給大家介紹了cron 表達(dá)式的解釋,需要的朋友一起看看吧
    2017-11-11

最新評(píng)論