使用Springboot3.x結(jié)合美學(xué)與功能的設(shè)計(jì)實(shí)現(xiàn)藝術(shù)風(fēng)格驗(yàn)證碼
這個(gè)專(zhuān)題深入淺出地探討了各類(lèi)驗(yàn)證碼的生成和在Springboot3.x中的實(shí)踐,從基礎(chǔ)的滑動(dòng)、點(diǎn)選、算術(shù)運(yùn)算驗(yàn)證碼到創(chuàng)新的藝術(shù)風(fēng)格、水印、二維碼驗(yàn)證碼,適合所有Java開(kāi)發(fā)者閱讀。在這個(gè)專(zhuān)題中,不僅可以學(xué)習(xí)到技術(shù)實(shí)踐,更能領(lǐng)略到驗(yàn)證碼的美學(xué)魅力。讓我們一起探索驗(yàn)證碼的無(wú)盡可能性。
什么是藝術(shù)風(fēng)格驗(yàn)證碼
驗(yàn)證碼,全名叫做 Completely Automated Public Turing Test to tell Computers and Humans Apart(全自動(dòng)區(qū)分計(jì)算機(jī)和人類(lèi)的圖靈測(cè)試)。其主要目標(biāo)是阻止機(jī)器自動(dòng)進(jìn)行某些操作,例如注冊(cè)用戶(hù)、提交表單等。
而藝術(shù)風(fēng)格驗(yàn)證碼,可以看作是驗(yàn)證碼的一種創(chuàng)新形式,它將數(shù)字藝術(shù)融入到這項(xiàng)安全措施中。藝術(shù)風(fēng)格驗(yàn)證碼的外觀吸引人,增強(qiáng)了用戶(hù)體驗(yàn),同時(shí)也提高了驗(yàn)證碼的安全等級(jí)。因?yàn)檫@種驗(yàn)證碼在視覺(jué)上的差異性和復(fù)雜性使得對(duì)驗(yàn)證碼的自動(dòng)識(shí)別變得更加困難,提高了安全性。
所謂藝術(shù)風(fēng)格,包括但不限于各種視覺(jué)藝術(shù)形式,例如流行藝術(shù)、抽象藝術(shù)、最小主義藝術(shù)等。驗(yàn)證碼的顏色、形狀、過(guò)濾效果等都可以根據(jù)特定的藝術(shù)風(fēng)格來(lái)設(shè)計(jì)。例如,我們可能將驗(yàn)證碼中的數(shù)字或字母渲染成流行藝術(shù)風(fēng)格,或者給驗(yàn)證碼背景添加抽象藝術(shù)元素。
藝術(shù)風(fēng)格驗(yàn)證碼的運(yùn)行機(jī)制
藝術(shù)風(fēng)格驗(yàn)證碼的運(yùn)行機(jī)制同普通驗(yàn)證碼非常相似,但是它引入了額外的步驟來(lái)添加藝術(shù)效果。以下是其一般的工作流程:
- 生成一組隨機(jī)的字母或數(shù)字作為驗(yàn)證碼的原始文本。
- 為每個(gè)字符生成一個(gè)基本的圖形表示,通常是在圖片中為每個(gè)字符分配一個(gè)特定的位置并進(jìn)行繪制。
- 對(duì)生成的圖片應(yīng)用一系列藝術(shù)效果。這些效果可以包含顏色變換、模糊處理、波紋效果、旋轉(zhuǎn)變形等。
- 將完成藝術(shù)效果處理的驗(yàn)證碼圖片展示給用戶(hù),并存儲(chǔ)原始的驗(yàn)證碼文本以供用戶(hù)提交后進(jìn)行比對(duì)驗(yàn)證。
下面通過(guò)一個(gè)基本的例子演示在Java環(huán)境下如何通過(guò)代碼實(shí)現(xiàn)這個(gè)流程:
public void generateArtisticVerificationCode() {
String verificationCode = RandomStringUtils.randomAlphanumeric(5); // 生成原始驗(yàn)證碼文本
BufferedImage image = new BufferedImage(100, 40, BufferedImage.TYPE_INT_ARGB); // 創(chuàng)建圖片對(duì)象
Graphics graphics = image.getGraphics(); // 獲取畫(huà)布
graphics.setFont(new Font("TimesRoman", Font.BOLD, 20)); // 設(shè)定字體
graphics.setColor(Color.BLACK); // 設(shè)定顏色
for (int i = 0; i < verificationCode.length(); i++) {
graphics.drawString(verificationCode.charAt(i) + "", 10 + i * 16, 28); // 在畫(huà)布上繪制每個(gè)字符
}
applyArtisticEffects(image); // 應(yīng)用藝術(shù)效果
// 將圖片展示給用戶(hù),同時(shí)保留原始驗(yàn)證碼文本以供后續(xù)驗(yàn)證
}
// 示例藝術(shù)效果應(yīng)用函數(shù)
public void applyArtisticEffects(BufferedImage image) {
// 這個(gè)函數(shù)會(huì)對(duì)圖片應(yīng)用各種藝術(shù)效果,包括但不限于顏色變換、模糊處理、波紋效果等
// 具體實(shí)現(xiàn)取決于你希望生成驗(yàn)證碼的藝術(shù)風(fēng)格
}
在生成藝術(shù)風(fēng)格驗(yàn)證碼的過(guò)程中,我們首先生成了原始的驗(yàn)證碼文本,并為每一個(gè)字符在圖片上繪制了基本的圖形表示。然后我們對(duì)圖片應(yīng)用了藝術(shù)效果處理。最后我們將處理過(guò)的驗(yàn)證碼圖片展示給用戶(hù),并保留原始的驗(yàn)證碼文本,這樣用戶(hù)在提交時(shí)我們就可以對(duì)提交的驗(yàn)證碼和原始的進(jìn)行比對(duì)。
技術(shù)實(shí)現(xiàn):在Springboot3.x中如何生成藝術(shù)風(fēng)格驗(yàn)證碼
在Springboot3.x中生成藝術(shù)風(fēng)格驗(yàn)證碼,我們主要分為以下幾步:
- 創(chuàng)建驗(yàn)證碼Controller
- 實(shí)現(xiàn)一個(gè)驗(yàn)證碼服務(wù)
- 實(shí)現(xiàn)一個(gè)藝術(shù)效果應(yīng)用服務(wù)
以下是詳細(xì)的實(shí)現(xiàn)步驟和示例代碼:
創(chuàng)建驗(yàn)證碼Controller
首先,我們需要?jiǎng)?chuàng)建一個(gè)Controller用于處理驗(yàn)證碼相關(guān)的請(qǐng)求。這個(gè)Controller將和我們的驗(yàn)證碼服務(wù)進(jìn)行交互,接收用戶(hù)請(qǐng)求并返回生成的驗(yàn)證碼。
@RestController
public class VerificationCodeController {
@Autowired
private VerificationCodeService verificationCodeService;
@RequestMapping("/verificationCode")
public void getVerificationCode(HttpServletResponse response, HttpSession session) {
BufferedImage image = verificationCodeService.createVerificationImage();
session.setAttribute("VERIFICATION_CODE", verificationCodeService.getVerificationCode());
ImageIO.write(image, "jpeg", response.getOutputStream());
}
}
在上述代碼中,我們創(chuàng)建了一個(gè)名為VerificationCodeController的Controller。我們注入了VerificationCodeService用于生成驗(yàn)證碼。我們定義了一個(gè)路由/verificationCode,用于接收HTTP請(qǐng)求并返回生成的驗(yàn)證碼圖片。
實(shí)現(xiàn)驗(yàn)證碼服務(wù)
驗(yàn)證碼服務(wù)的責(zé)任是生成原始的驗(yàn)證碼文本和驗(yàn)證碼圖片。
@Service
public class VerificationCodeService {
@Autowired
private ArtisticEffectService artisticEffectService;
private String verificationCode;
public BufferedImage createVerificationImage() {
verificationCode = RandomStringUtils.randomAlphanumeric(5);
BufferedImage image = new BufferedImage(100, 40, BufferedImage.TYPE_INT_ARGB);
Graphics graphics = image.getGraphics();
graphics.setFont(new Font("TimesRoman", Font.BOLD, 20));
graphics.setColor(Color.BLACK);
for (int i = 0; i < verificationCode.length(); i++) {
graphics.drawString(verificationCode.charAt(i) + "", 10 + i * 16, 28);
}
artisticEffectService.applyArtisticEffects(image);
return image;
}
public String getVerificationCode() {
return verificationCode;
}
}
實(shí)現(xiàn)藝術(shù)效果應(yīng)用服務(wù)
藝術(shù)效果應(yīng)用服務(wù)用于對(duì)驗(yàn)證碼圖片應(yīng)用藝術(shù)效果。
@Service
public class import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import org.springframework.stereotype.Service;
@Service
public class ArtisticEffectService {
public void applyArtisticEffects(BufferedImage image) {
Graphics2D graphics = (Graphics2D) image.getGraphics();
// 添加線性漸變效果
GradientPaint paint = new GradientPaint(0, 0, Color.BLUE, image.getWidth(), 0, Color.RED);
graphics.setPaint(paint);
graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.5f));
graphics.fillRect(0, 0, image.getWidth(), image.getHeight());
// 添加模糊效果
float ninth = 1.0f/9.0f;
float[] blurKernel = {
ninth, ninth, ninth,
ninth, ninth, ninth,
ninth, ninth, ninth
};
ConvolveOp op = new ConvolveOp(new Kernel(3, 3, blurKernel));
BufferedImage blurredImage = op.filter(image, null);
graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
graphics.drawImage(blurredImage, 0, 0, null);
}
}
在上述代碼中,我們首先使用GradientPaint創(chuàng)建了一個(gè)從左邊的藍(lán)色向右邊的紅色逐漸變化的線性漸變效果,然后使用AlphaComposite將這個(gè)漸變效果和原來(lái)的圖像合成在一起。
接著,我們創(chuàng)建了一個(gè)模糊核(blur kernel)并使用ConvolveOp將模糊效果應(yīng)用到現(xiàn)有的圖像上。
實(shí)戰(zhàn)應(yīng)用:藝術(shù)風(fēng)格驗(yàn)證碼的應(yīng)用示例
在接下來(lái)的示例中,我們將實(shí)現(xiàn)一個(gè)功能更為完善的Spring Boot應(yīng)用程序,該程序包含一個(gè)Web頁(yè)面,用戶(hù)可以從該頁(yè)面請(qǐng)求新的藝術(shù)風(fēng)格驗(yàn)證碼,并提交輸入以進(jìn)行驗(yàn)證。
以下是我們的應(yīng)用程序的主要組件:
- 驗(yàn)證碼生成服務(wù)
- Web控制器
- Vue.js前端應(yīng)用
驗(yàn)證碼生成服務(wù)
我們先前已經(jīng)實(shí)現(xiàn)了一個(gè)驗(yàn)證碼服務(wù)和藝術(shù)效果服務(wù),現(xiàn)在我們可以將其集成到我們的Spring Boot應(yīng)用中。
@Service
public class VerificationCodeService {
private String verificationCode;
@Autowired
private ArtisticEffectService artisticEffectService;
public String createVerificationCode() {
verificationCode = RandomStringUtils.randomAlphanumeric(5);
return verificationCode;
}
public BufferedImage createVerificationImage() {
String code = createVerificationCode();
BufferedImage image = new BufferedImage(100, 40, BufferedImage.TYPE_INT_ARGB);
Graphics graphics = image.getGraphics();
graphics.setFont(new Font("Arial", Font.BOLD, 24));
graphics.setColor(Color.BLACK);
for (int i = 0; i < verificationCode.length(); i++) {
graphics.drawString(code.charAt(i) + "", 10 + i * 16, 32);
}
artisticEffectService.applyArtisticEffects(image);
return image;
}
public boolean verifyCode(String userInput) {
return userInput.equals(verificationCode);
}
}
在這里,我們將為這個(gè)方法實(shí)現(xiàn)傾斜角度變化和圖片抖動(dòng)這兩種常見(jiàn)的藝術(shù)樣式。
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.util.Random;
import org.springframework.stereotype.Service;
@Service
public class ArtisticEffectService {
// 旋轉(zhuǎn)給定的圖像
public BufferedImage rotateImage(BufferedImage image) {
int width = image.getWidth();
int height = image.getHeight();
BufferedImage rotatedImage = new BufferedImage(width, height, image.getType());
Graphics2D graphics2D = rotatedImage.createGraphics();
double theta = Math.toRadians(new Random().nextInt(40) - 20); // 在-20到20度之間隨機(jī)旋轉(zhuǎn)
graphics2D.rotate(theta, width / 2, height / 2);
graphics2D.drawImage(image, 0, 0, null);
graphics2D.dispose();
return rotatedImage;
}
// 對(duì)給定的字符串應(yīng)用底噪音和干擾線
public BufferedImage applyArtisticEffects(BufferedImage image) {
int width = image.getWidth();
int height = image.getHeight();
Random random = new Random();
// 底部噪聲
for (int i = 0; i < 30; i++) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int rgb = getRandomRgb();
image.setRGB(x, y, rgb);
}
// 干擾線
Graphics2D graphics2D = image.createGraphics();
for (int i = 0; i < 5; i++) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(width);
int yl = random.nextInt(height);
graphics2D.setColor(new Color(getRandomRgb()));
graphics2D.drawLine(x, y, x + xl, y + yl);
}
graphics2D.dispose();
return rotateImage(image);
}
// 生成隨機(jī)的RGB顏色
private int getRandomRgb() {
Random random = new Random();
int red = random.nextInt(256);
int green = random.nextInt(256);
int blue = random.nextInt(256);
return (red << 16) | (green << 8) | blue;
}
}
在上述代碼中,我們首先為驗(yàn)證碼圖片添加底部噪聲和干擾線,然后隨機(jī)地旋轉(zhuǎn)圖片角度。這將確保每一次生成的驗(yàn)證碼圖片都是獨(dú)一無(wú)二的,并能有效地防止機(jī)器人自動(dòng)識(shí)別。
Web控制器
接下來(lái),我們需要?jiǎng)?chuàng)建一個(gè)Web控制器來(lái)處理用戶(hù)的HTTP請(qǐng)求。我們將創(chuàng)建兩個(gè)路由,一個(gè)用于生成和獲取驗(yàn)證碼,另一個(gè)用于驗(yàn)證用戶(hù)輸入的驗(yàn)證碼。
@RestController
@RequestMapping("/api")
public class VerificationCodeController {
@Autowired
private VerificationCodeService verificationCodeService;
@GetMapping("/verificationCode")
public ResponseEntity<byte[]> getVerificationCode() throws IOException {
BufferedImage image = verificationCodeService.createVerificationImage();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageIO.write(image, "png", bos);
byte[] imageBytes = bos.toByteArray();
return ResponseEntity.ok().contentType(MediaType.IMAGE_PNG).body(imageBytes);
}
@PostMapping("/verify")
public ResponseEntity<Boolean> verifyCode(@RequestBody String userInput) {
boolean isCorrect = verificationCodeService.verifyCode(userInput);
return ResponseEntity.ok(isCorrect);
}
}
在上述代碼中,getVerificationCode方法處理GET請(qǐng)求并返回新的驗(yàn)證碼圖像。我們將返回的驗(yàn)證碼圖像存儲(chǔ)為一個(gè)字節(jié)數(shù)組,以便將其作為HTTP響應(yīng)的一部分發(fā)送回客戶(hù)端。
verifyCode方法接收用戶(hù)的驗(yàn)證碼輸入,并通過(guò)與存儲(chǔ)在服務(wù)端的驗(yàn)證碼進(jìn)行比較來(lái)驗(yàn)證輸入是否正確。
前端應(yīng)用
綜合以上所述,我們已經(jīng)成功地在后端實(shí)現(xiàn)驗(yàn)證碼的生成和驗(yàn)證?,F(xiàn)在,我們需要一個(gè)前端用戶(hù)界面來(lái)顯示驗(yàn)證碼,并提供一個(gè)輸入框讓用戶(hù)輸入驗(yàn)證碼。
在這個(gè)例子中,我們將使用Vue.js來(lái)實(shí)現(xiàn)前端應(yīng)用。前端應(yīng)用將包含一個(gè)圖像組件用來(lái)顯示驗(yàn)證碼,一個(gè)文本框用于用戶(hù)輸入,以及一個(gè)按鈕用于提交用戶(hù)輸入。
<template>
<div id="app">
<img :src="`data:image/png;base64,${captchaImage}`" @click="refreshCaptcha" />
<input v-model="userInput" type="text" placeholder="Enter the captcha" />
<button @click="verifyCaptcha">Submit</button>
</div>
</template>
<script>
export default {
data() {
return {
captchaImage: '',
userInput: ''
}
},
methods: {
refreshCaptcha() {
axios.get('/api/verificationCode', { responseType: 'arraybuffer' })
.then(response => {
let base64 = btoa(new Uint8Array(response.data).reduce((data, byte) => data + String.fromCharCode(byte), ''));
this.captchaImage = base64;
});
},
verifyCaptcha() {
axios.post('/api/verify', this.userInput)
.then(response => {
if (response.data) {
alert("The captcha is correct.");
} else {
alert("The captcha is incorrect.");
this.refreshCaptcha();
}
});
}
},
mounted() {
this.refreshCaptcha();
}
}
</script>
在上述代碼中,我們使用Vue.js提供的兩個(gè)生命周期鉤子:methods中的refreshCaptcha方法獲取新的驗(yàn)證碼,mounted中的refreshCaptcha在頁(yè)面加載時(shí)調(diào)用。在驗(yàn)證碼提交后,一個(gè)警告會(huì)告訴用戶(hù)提交的驗(yàn)證碼是否正確。如果驗(yàn)證碼不正確,將會(huì)刷新新的驗(yàn)證碼。
通過(guò)這種方式,我們成功創(chuàng)建了一個(gè)藝術(shù)風(fēng)格驗(yàn)證碼的完整應(yīng)用示例,包含后端的驗(yàn)證碼生成、前端的驗(yàn)證碼展示和用戶(hù)輸入驗(yàn)證等完整流程。
本文主要介紹了如何實(shí)現(xiàn)一個(gè)藝術(shù)風(fēng)格的驗(yàn)證碼系統(tǒng),過(guò)程包含生成驗(yàn)證碼、應(yīng)用藝術(shù)效果、及其在前后端的實(shí)現(xiàn)。驗(yàn)證碼生成部分,通過(guò)Java的RandomStringUtils工具生成隨機(jī)字符串作為驗(yàn)證碼。藝術(shù)效果應(yīng)用部分,實(shí)現(xiàn)了噪點(diǎn)擾動(dòng)和模糊效果,來(lái)增強(qiáng)驗(yàn)證碼的安全性同時(shí)賦予其獨(dú)特的藝術(shù)風(fēng)格。在后端,我們創(chuàng)建了一個(gè)Spring Boot應(yīng)用,實(shí)現(xiàn)了驗(yàn)證碼的生成并返回給前端;在前端部分,我們使用Vue.js創(chuàng)建了一個(gè)用戶(hù)界面單元,用戶(hù)可以進(jìn)行驗(yàn)證碼的獲取與輸入驗(yàn)證。這樣的系統(tǒng)結(jié)構(gòu)使得驗(yàn)證碼的生成及驗(yàn)證過(guò)程更為靈活與高效。