我們先來看效果:
(學習影片推薦:java課程)
#一、適用需求
後台產生驗證碼,用於登陸驗證。
二、實作流程
1、視圖層思路
(1)input用來輸入驗證碼,一個img用來展示驗證碼
# (2)校驗輸入的驗證碼是否合格,雙擊img刷新驗證碼,綁定onblue失去焦點事件(滑鼠失去焦點時觸發的事件)
(3)onblue事件中做校驗,
(4)img中的src屬性值為後台產生驗證碼的方法請求路徑(即requestMapping的路徑),再點擊驗證碼的時候,再動態設定src屬性即可(原始存取位址隨機時間戳,防止同一路徑瀏覽器不另做訪問的問題)
注意:後台直接返回圖片,不是驗證碼的字符!若返回字符,則驗證碼就失去了意義(前台很容易就可以取得驗證碼字符,進行多次惡意存取了)(這點考慮了系統安全性)
2、後端思路
利用BufferedImage類別建立一張圖片,再用Graphics2D對圖片進行繪製(產生隨機字符,加入乾擾線)即可,注意:產生的驗證碼字串要放到session中,用於接下來登陸的驗證碼驗證(當然也是後台)。
前端程式碼如下:
验证码: /** * 校验字段是否为空 */ function checkNull(name,msg){ setMsg(name,"") var v = document.getElementsByName(name)[0].value; if(v == ""){ setMsg(name,msg) return false; } return true; } /** * 为输入项设置提示消息 */ function setMsg(name,msg){ var span = document.getElementById(name+"_msg"); span.innerHTML=""+msg+""; } /** * 点击更换验证码 */ function changeYZM(imgObj){ imgObj.src = "${pageContext.request.contextPath}/servlet/ValiImgServlet?time="+new Date().getTime(); }
後端程式碼如下:
package cn.tedu.web; import cn.tedu.util.VerifyCode; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; /** * 获取验证码 */ public class ValiImgServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //禁止浏览器缓存验证码 response.setDateHeader("Expires",-1); response.setHeader("Cache-Control","no-cache"); response.setHeader("Pragma","no-cache"); //生成验证码 VerifyCode vc = new VerifyCode(); //输出验证码 vc.drawImage(response.getOutputStream()); //获取验证码的值,存储到session中 String valistr = vc.getCode(); HttpSession session = request.getSession(); session.setAttribute("valistr",valistr); //打印到控制台 System.out.println(valistr); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }
package cn.tedu.util; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.OutputStream; import java.util.Random; import javax.imageio.ImageIO; /** * 动态生成图片 */ public class VerifyCode { // {"宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", "楷体_GB2312"} private static String[] fontNames = { "宋体", "华文楷体", "黑体", "微软雅黑", "楷体_GB2312" }; // 可选字符 //"23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ"; private static String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ"; // 背景色 private Color bgColor = new Color(255, 255, 255); // 基数(一个文字所占的空间大小) private int base = 30; // 图像宽度 private int width = base * 4; // 图像高度 private int height = base; // 文字个数 private int len = 4; // 设置字体大小 private int fontSize = 22; // 验证码上的文本 private String text; private BufferedImage img = null; private Graphics2D g2 = null; /** * 生成验证码图片 */ public void drawImage(OutputStream outputStream) { // 1.创建图片缓冲区对象, 并设置宽高和图像类型 img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 2.得到绘制环境 g2 = (Graphics2D) img.getGraphics(); // 3.开始画图 // 设置背景色 g2.setColor(bgColor); g2.fillRect(0, 0, width, height); StringBuffer sb = new StringBuffer();// 用来装载验证码上的文本 for (int i = 0; i < len; i++) { // 设置画笔颜色 -- 随机 // g2.setColor(new Color(255, 0, 0)); g2.setColor(new Color(getRandom(0, 150), getRandom(0, 150),getRandom(0, 150))); // 设置字体 g2.setFont(new Font(fontNames[getRandom(0, fontNames.length)], Font.BOLD, fontSize)); // 旋转文字(-45~+45) int theta = getRandom(-45, 45); g2.rotate(theta * Math.PI / 180, 7 + i * base, height - 8); // 写字 String code = codes.charAt(getRandom(0, codes.length())) + ""; g2.drawString(code, 7 + i * base, height - 8); sb.append(code); g2.rotate(-theta * Math.PI / 180, 7 + i * base, height - 8); } this.text = sb.toString(); // 画干扰线 for (int i = 0; i < len + 2; i++) { // 设置画笔颜色 -- 随机 // g2.setColor(new Color(255, 0, 0)); g2.setColor(new Color(getRandom(0, 150), getRandom(0, 150), getRandom(0, 150))); g2.drawLine(getRandom(0, 120), getRandom(0, 30), getRandom(0, 120), getRandom(0, 30)); } //TODO: g2.setColor(Color.GRAY); g2.drawRect(0, 0, this.width-1, this.height-1); // 4.保存图片到指定的输出流 try { ImageIO.write(this.img, "JPEG", outputStream); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); }finally{ // 5.释放资源 g2.dispose(); } } /** * 获取验证码字符串 * @return */ public String getCode() { return this.text; } /* * 生成随机数的方法 */ private static int getRandom(int start, int end) { Random random = new Random(); return random.nextInt(end - start) + start; } /*public static void main(String[] args) throws Exception { VerifyCode vc = new VerifyCode(); vc.drawImage(new FileOutputStream("f:/vc.jpg")); System.out.println("执行成功~!"); }*/ }
總結:
簡介:是「Completely Automated Public Turing test to tell Computers and Humans Apart」(全自動區分電腦和人類的圖靈測試)的縮寫,是一種區分使用者是電腦還是人的公共全自動程式。
歷史:是「Completely Automated Public Turing test to tell Computers and Humans Apart」(全自動區分電腦與人類的圖靈測試)的縮寫,是一種區分使用者是電腦還是人的公共全自動程式.
作用:防止惡意破解密碼、刷票、論壇灌水、刷頁。
分類:Gif動畫驗證碼,手機簡訊驗證碼,手機語音驗證碼,視訊驗證碼
#常見的驗證碼:
(1)四位數字和字母,可能都是字母,也可能都是數字,隨機的4位字串,最原始的驗證碼,驗證作用幾乎為零。 CSDN網站用戶登入用的是GIF格式,常用的隨機數字圖片驗證碼。圖片上的字元比較中規中矩,驗證效果比前一個好。
(2)漢字是註冊目前最新的驗證碼,隨機生成,打起來比較難,例如QQ申訴頁面。
(3)MS的hotmail申請時候的是BMP格式, 隨機數字 隨機大寫英文字母 隨機幹擾像素 隨機位置。
(4)韓文或日文,現在跑跑HF上MS註冊要打韓文,增加了難度。
(5)Google的Gmail註冊時候的是JPG格式,隨機英文字母 隨機顏色 隨機位置 隨機長度。
(6)其他各大論壇的是XBM格式,內容隨機
(7)廣告驗證碼:輸入廣告中的部分內容即可,特點是可以為網站帶來額外收入,也可以使使用者耳目一新。廣告驗證碼
(8)問題驗證碼:問題驗證碼主要是以問答式的形式來進行填寫。它的查看比加模驗證碼更容易辨別和錄入,系統可以產生諸如“1 2=?”的問題讓用戶進行回答,當然這樣的問題是隨機生成的。另一種問題驗證碼,則是文字式的問題驗證碼,諸如生成問題“中國的全稱是什麼?”,當然有些網站還在問題後面給出了提示答案或直接答案。
相關推薦:java入門
以上是利用java來產生後台驗證碼的詳細內容。更多資訊請關注PHP中文網其他相關文章!