Java實(shí)現(xiàn)圖片驗(yàn)證碼功能
簡(jiǎn)介
在實(shí)現(xiàn)登錄功能時(shí),一般為了安全都會(huì)設(shè)置驗(yàn)證碼登錄,為了防止某個(gè)用戶(hù)用特定的程序暴力破解方式進(jìn)行不斷的嘗試登錄。常見(jiàn)驗(yàn)證碼分為圖片驗(yàn)證碼和短信驗(yàn)證碼,還有滑動(dòng)窗口模塊和選中指定物體驗(yàn)證方式。下面通過(guò)Java來(lái)實(shí)現(xiàn)圖片驗(yàn)證碼實(shí)例。
效果展示
如上圖所示,圖片驗(yàn)證碼由4個(gè)數(shù)字和一些彩色的干擾線(xiàn)段組成,點(diǎn)擊圖片可以更新驗(yàn)證碼,只有輸入的驗(yàn)證碼與圖片中的數(shù)字一致才能通過(guò)登錄,否則將會(huì)重新刷新驗(yàn)證碼,重新輸入正確的驗(yàn)證碼。
示例代碼
1、controller
@RestController public class ValidateCodeController { ? ? @GetMapping("/getCodeImg") ? ? public void getCodeImage(HttpServletRequest request, HttpServletResponse response, HttpSession httpSession) throws IOException, InterruptedException { ? ? ? ? BufferedImage image=new BufferedImage(80, 32, BufferedImage.TYPE_3BYTE_BGR); ? ? ? ? //編輯圖像 ? ? ? ? //獲取繪圖對(duì)象 ? ? ? ? Graphics g=image.getGraphics(); ? ? ? ? g.setColor(new Color(239, 239, 239)); ? ? ? ? g.fillRect(0,0,80,32); ? ? ? ? //設(shè)置字體顏色 ? ? ? ? g.setColor(new Color(49, 49, 49)); ? ? ? ? //設(shè)置字體 ? ? ? ? g.setFont(new Font("SimSong",Font.ITALIC,20)); ? ? ? ? //繪制字符串; ? ? ? ? String text=""; ? ? ? ? for(int i=0;i<4;i++) { ? ? ? ? ? ? text +=(int) (Math.random()*10); ? ? ? ? } ? ? ? ? //字符串輸出內(nèi)容,水平起始坐標(biāo),垂直起始坐標(biāo)。 ? ? ? ? g.drawString(text, 17, 24); ? ? ? ? //畫(huà)線(xiàn)條 ? ? ? ? for (int i = 0; i < 10; i++) { ? ? ? ? ? ? g.setColor(new Color((int) (Math.random()*255), (int) (Math.random()*255), (int) (Math.random()*255))); ? ? ? ? ? ? g.drawLine((int) (Math.random()*50),(int) (Math.random()*30),(int) (Math.random()*80),(int) (Math.random()*80)); ? ? ? ? } ? ? ? ? //設(shè)置session ? ? ? ? httpSession.setAttribute("code",text); ? ? ? ? //輸出圖像 ? ? ? ? //ImageIO.write(image, "png", new FileOutputStream("C:/Users/H/Desktop/"+tet+".png")); ? ? ? ? ImageIO.write(image, "png",response.getOutputStream()); ? ? ? ? g.dispose(); ? ? } ?? ?//獲取保存在session中的驗(yàn)證碼 ? ? @GetMapping("/getCode") ? ? public String getCode(HttpSession httpSession){ ? ? ? ? return (String) httpSession.getAttribute("code"); ? ? } }
2、登錄頁(yè)面
<body> <div class="layui-container" id="container"> ? ? <!--登錄--> ? ? <div class="login" id="login"> ? ? ? ? <h3 class="header">登 陸</h3> ? ? ? ? <span style="color: red;font-weight: 800">{{msg}}</span> ? ? ? ? <form class="layui-form loginForm" th:action="@{/}" method="get" @submit.prevent="check()" ref="export"> ? ? ? ? ? ? <div class="layui-form-item"> ? ? ? ? ? ? ? ? <label class="layui-form-label">登錄名</label> ? ? ? ? ? ? ? ? <div class="layui-input-block" style="width: 330px"> ? ? ? ? ? ? ? ? ? ? <input type="text" name="username" required ?lay-verify="required" placeholder="請(qǐng)輸入登錄名" autocomplete="off" class="layui-input" v-model="userName" @blur="loseFocus()" @focus="getFocus()"> ? ? ? ? ? ? ? ? </div> ? ? ? ? ? ? </div> ? ? ? ? ? ? <div class="layui-form-item"> ? ? ? ? ? ? ? ? <label class="layui-form-label">密 碼</label> ? ? ? ? ? ? ? ? <div class="layui-input-block" style="width: 330px"> ? ? ? ? ? ? ? ? ? ? <input type="password" required ?lay-verify="required" placeholder="請(qǐng)輸入密碼" autocomplete="off" class="layui-input" v-model="userPwd" name="password" @focus="getFocus()"> ? ? ? ? ? ? ? ? </div> ? ? ? ? ? ? </div> ? ? ? ? ? ? <div class="layui-form-item"> ? ? ? ? ? ? ? ? <label class="layui-form-label">驗(yàn)證碼</label> ? ? ? ? ? ? ? ? <div class="layui-input-block" style="width: 200px"> ? ? ? ? ? ? ? ? ? ? <input type="text" required ?lay-verify="required" placeholder="請(qǐng)輸入驗(yàn)證碼" autocomplete="off" class="layui-input" v-model="code" name="code" @blur="validateCode()" @focus="getFocus()"> ? ? ? ? ? ? ? ? </div> ? ? ? ? ? ? ? ? <img class="code" src="/getCodeImg" @click="changeCode()" id="codeImg"> ? ? ? ? ? ? </div> ? ? ? ? ? ? <div class="layui-form-item"> ? ? ? ? ? ? ? ? <div class="layui-input-block" style="margin: 0 auto"> ? ? ? ? ? ? ? ? ? ? <button type="submit" class="layui-btn " lay-submit lay-filter="formDemo">登錄</button> ? ? ? ? ? ? ? ? ? ? <button type="button" class="layui-btn layui-btn-normal" id="reg">注冊(cè)</button> ? ? ? ? ? ? ? ? </div> ? ? ? ? ? ? </div> ? ? ? ? </form> ? ? </div> <!-- ? ?注冊(cè)--> ? ? <div class="register" id="register"> ? ? ? ? <h3 class="header">注 冊(cè)</h3> ? ? ? ? <span style="color: red;font-weight: 800">{{msg2}}</span> ? ? ? ? <form class="layui-form loginForm" th:action="@{/login}" method="post" @submit.prevent="check()" ref="export"> ? ? ? ? ? ? <div class="layui-form-item"> ? ? ? ? ? ? ? ? <label class="layui-form-label">登錄名</label> ? ? ? ? ? ? ? ? <div class="layui-input-block" style="width: 330px"> ? ? ? ? ? ? ? ? ? ? <input type="text" name="username" required ?lay-verify="required" placeholder="請(qǐng)輸入登錄名" autocomplete="off" class="layui-input" v-model="userName" @blur="loseFocus()" @focus="getFocus()"> ? ? ? ? ? ? ? ? </div> ? ? ? ? ? ? </div> ? ? ? ? ? ? <div class="layui-form-item"> ? ? ? ? ? ? ? ? <label class="layui-form-label">密 碼</label> ? ? ? ? ? ? ? ? <div class="layui-input-block" style="width: 330px"> ? ? ? ? ? ? ? ? ? ? <input type="password" required ?lay-verify="required" placeholder="請(qǐng)輸入密碼" autocomplete="off" class="layui-input" v-model="userPwd" name="password" @focus="getFocus()"> ? ? ? ? ? ? ? ? </div> ? ? ? ? ? ? </div> ? ? ? ? ? ? <div class="layui-form-item"> ? ? ? ? ? ? ? ? <label class="layui-form-label">確認(rèn)密碼</label> ? ? ? ? ? ? ? ? <div class="layui-input-block" style="width: 330px"> ? ? ? ? ? ? ? ? ? ? <input type="password" required ?lay-verify="required" placeholder="請(qǐng)?jiān)俅屋斎朊艽a" autocomplete="off" class="layui-input" v-model="rePassword" ?name="rePassword" @focus="getFocus()"> ? ? ? ? ? ? ? ? </div> ? ? ? ? ? ? </div> ? ? ? ? ? ? <div class="layui-form-item"> ? ? ? ? ? ? ? ? <label class="layui-form-label">郵 箱</label> ? ? ? ? ? ? ? ? <div class="layui-input-block" style="width: 330px"> ? ? ? ? ? ? ? ? ? ? <input type="email" required ?lay-verify="required" placeholder="請(qǐng)輸入郵箱" autocomplete="off" class="layui-input" v-model="userEmail" name="userEmail" @blur="validateCode()" @focus="getFocus()"> ? ? ? ? ? ? ? ? </div> ? ? ? ? ? ? </div> ? ? ? ? ? ? <div class="layui-form-item"> ? ? ? ? ? ? ? ? <div class="layui-input-block" style="margin: 0 auto"> ? ? ? ? ? ? ? ? ? ? <button type="button" class="layui-btn " lay-submit lay-filter="formDemo" @click="addUser()">注冊(cè)</button> ? ? ? ? ? ? ? ? ? ? <button type="reset" class="layui-btn layui-btn-normal" lay-submit lay-filter="formDemo">重置</button> ? ? ? ? ? ? ? ? </div> ? ? ? ? ? ? </div> ? ? ? ? </form> ? ? </div> </div> </body>
3、JavaScript
var vm = new Vue({ ? ? ? ? el:'#container', ? ? ? ? data:{ ? ? ? ? ? ? userName:'', ? ? ? ? ? ? userPwd:'', ? ? ? ? ? ? userEmail: '', ? ? ? ? ? ? rePassword:'', ? ? ? ? ? ? msg:'', ? ? ? ? ? ? msg2:'', ? ? ? ? ? ? code:'', ? ? ? ? ? ? text:'' ? ? ? ? }, ? ? ? ? methods:{ ? ? ? ? ? ? changeCode:function(){ ? ? ? ? ? ? ? ? // 如果src里的圖片鏈接不變的話(huà),會(huì)直接用緩存的圖片,加上Math.random()是為了讓src的圖片鏈接改變重新去渲染圖片 ? ? ? ? ? ? ? ? document.getElementById("codeImg").src="/getCodeImg?"+Math.random(); ? ? ? ? ? ? }, ? ? ? ? ? ? validateCode:function () { ? ? ? ? ? ? ? ? vm.$http.get('/getCode').then((response)=>{ ? ? ? ? ? ? ? ? ? ? this.text=response.data ? ? ? ? ? ? ? ? }) ? ? ? ? ? ? }, ? ? ? ? ? ? addUser:function (){ ? ? ? ? ? ? ? ? if (vm.userPwd !== vm.rePassword){ ? ? ? ? ? ? ? ? ? ? vm.msg2="確認(rèn)密碼不正確!" ? ? ? ? ? ? ? ? }else { ? ? ? ? ? ? ? ? ? ? vm.$http.post('/user/add/'+vm.userName+'/'+vm.userPwd+'/'+vm.userEmail).then((response)=>{ ? ? ? ? ? ? ? ? ? ? ? ? window.location.href='/' ? ? ? ? ? ? ? ? ? ? }) ? ? ? ? ? ? ? ? } ? ? ? ? ? ? }, ? ? ? ? ? ? loseFocus:function () { ? ? ? ? ? ? ? ? vm.$http.get('/user/queryUserByName/'+vm.userName).then((response)=>{ ? ? ? ? ? ? ? ? ? ? if (response.data.userName!==vm.userName){ ? ? ? ? ? ? ? ? ? ? ? ? vm.msg="該用戶(hù)名不存在!" ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? }) ? ? ? ? ? ? }, ? ? ? ? ? ? getFocus:function(){ ? ? ? ? ? ? ? ? vm.msg="" ? ? ? ? ? ? }, ? ? ? ? ? ? check:function () { ? ? ? ? ? ? ? ? if (vm.userName===""){ ? ? ? ? ? ? ? ? ? ? vm.msg="用戶(hù)名為空!" ? ? ? ? ? ? ? ? ? ? return ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? if (vm.userPwd===""){ ? ? ? ? ? ? ? ? ? ? vm.msg="密碼為空!" ? ? ? ? ? ? ? ? ? ? return ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? if (vm.code===""){ ? ? ? ? ? ? ? ? ? ? vm.msg="驗(yàn)證碼為空!" ? ? ? ? ? ? ? ? ? ? return ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? vm.$http.post('/user/query/'+vm.userName+'/'+vm.userPwd).then((response)=>{ ? ? ? ? ? ? ? ? ? ? if (response.data.userName!==vm.userName){ ? ? ? ? ? ? ? ? ? ? ? ? vm.msg="密碼錯(cuò)誤!" ? ? ? ? ? ? ? ? ? ? }else if (vm.code!=vm.text){ ? ? ? ? ? ? ? ? ? ? ? ? vm.msg="驗(yàn)證碼錯(cuò)誤!" ? ? ? ? ? ? ? ? ? ? ? ? document.getElementById("codeImg").src="/getCodeImg?"+Math.random(); ? ? ? ? ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? ? ? ? ? vm.$refs.export.submit() ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? }) ? ? ? ? ? ? } ? ? ? ? } })
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java?超詳細(xì)講解Spring?MVC異常處理機(jī)制
Spring?MVC中提供了一個(gè)通用的異常處理機(jī)制,它提供了一個(gè)成熟、簡(jiǎn)潔并且清晰的異常處理方案。當(dāng)使用Spring?MVC開(kāi)發(fā)Web應(yīng)用時(shí),利用這套現(xiàn)成的機(jī)制進(jìn)行異常處理也更加自然并且高效2022-04-04java中char類(lèi)型轉(zhuǎn)換成int類(lèi)型的2種方法
這篇文章主要給大家介紹了關(guān)于java中char類(lèi)型轉(zhuǎn)換成int類(lèi)型的2種方法,因?yàn)閖ava是一門(mén)強(qiáng)類(lèi)型語(yǔ)言,所以在數(shù)據(jù)運(yùn)算中會(huì)存在類(lèi)型轉(zhuǎn)換,需要的朋友可以參考下2023-07-07如何使用Maven管理項(xiàng)目?Maven管理項(xiàng)目實(shí)例
下面小編就為大家?guī)?lái)一篇如何使用Maven管理項(xiàng)目?Maven管理項(xiàng)目實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06使用java采集京東商城行政區(qū)劃數(shù)據(jù)示例
這篇文章主要介紹了java采集京東的全國(guó)行政區(qū)劃數(shù)據(jù)示例,保存成json形式,如想轉(zhuǎn)換到數(shù)據(jù)庫(kù)只需反序列化為對(duì)象保存到數(shù)據(jù)庫(kù)即可2014-03-03java讀寫(xiě)ini文件、FileOutputStream問(wèn)題
這篇文章主要介紹了java讀寫(xiě)ini文件、FileOutputStream問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04springboot集成RestTemplate及常見(jiàn)的用法說(shuō)明
這篇文章主要介紹了springboot集成RestTemplate及常見(jiàn)的用法說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10Java實(shí)現(xiàn)斗地主最簡(jiǎn)代碼實(shí)例
在本篇文章里小編給各位分享的是關(guān)于Java實(shí)現(xiàn)斗地主最簡(jiǎn)代碼實(shí)例,有興趣的朋友們可以參考下。2020-05-05Jedis出現(xiàn)connection timeout問(wèn)題解決方法(JedisPool連接池使用實(shí)例)
這篇文章主要介紹了Jedis出現(xiàn)connection timeout問(wèn)題解決方法,使用Jedis的JedisPool連接池解決了這個(gè)問(wèn)題,需要的朋友可以參考下2014-05-05詳解Spring boot Admin 使用eureka監(jiān)控服務(wù)
本篇文章主要介紹了詳解Spring boot Admin 使用eureka監(jiān)控服務(wù),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12在spring-boot工程中添加spring mvc攔截器
這篇文章主要介紹了在spring-boot工程中添加spring mvc攔截器,Spring MVC的攔截器(Interceptor)不是Filter,同樣可以實(shí)現(xiàn)請(qǐng)求的預(yù)處理、后處理。,需要的朋友可以參考下2019-06-06