java實(shí)現(xiàn)圖片驗(yàn)證碼
本文實(shí)例為大家分享了java實(shí)現(xiàn)圖片驗(yàn)證碼的具體代碼,供大家參考,具體內(nèi)容如下
目的:
1) 驗(yàn)證操作者是否是人
2) 防止表單重復(fù)提交
生成驗(yàn)證碼的要點(diǎn):
1) 使用java代碼生成圖片對(duì)象
BufferedImage
2) 使用Random生成隨機(jī)字符串
3) 將圖片對(duì)象用
ImageIO.write(圖片對(duì)象, "jpeg|png", 響應(yīng)字節(jié)輸出流)
返回給客戶端瀏覽器
驗(yàn)證驗(yàn)證碼:
要點(diǎn):
1) 將驗(yàn)證碼文字存入session作用域
2) 表單提交時(shí),對(duì)比session中的驗(yàn)證碼和表單中的驗(yàn)證碼
CaptchaUtils.java
package cn.seeker.utils; ? import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.*; import java.util.List; ? public class CaptchaUtil { ? ? ? public static String [] fuhao = {"+","-","*","/"}; ? ? public static int num = 0; ? ? ? //生成隨機(jī)算式 ? ? public static String random(){ ? ? ? ? ? List list = new ArrayList(); ? ? ? ? Random ran = new Random(); ? ? ? ? int n1 = ran.nextInt(10); ? ? ? ? int n2 = ran.nextInt(10); ? ? ? ? String f = fuhao[ran.nextInt(fuhao.length)]; ? ? ? ? StringBuilder sb = new StringBuilder(4); ? ? ? ? ? switch (f){ ? ? ? ? ? ? case "+": ? ? ? ? ? ? ? ? num = n1+n2; ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? case "-": ? ? ? ? ? ? ? ? num =n1-n2; ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? case "*": ? ? ? ? ? ? ? ? num = n1*n2; ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? case "/": ? ? ? ? ? ? ? ? if(n2 == 0){ ? ? ? ? ? ? ? ? ? ? n2 = ran.nextInt(10)+1; ? ? ? ? ? ? ? ? ? ? num = n1/n2; ? ? ? ? ? ? ? ? }else{ ? ? ? ? ? ? ? ? ? ? num = n1/n2; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? break; ? ? ? ? } ? ? ? ? sb.append(n1); ? ? ? ? sb.append(f); ? ? ? ? sb.append(n2); ? ? ? ? sb.append("="); ? ? ? ? ? return sb.toString(); ? ? } ? ? public static void outputImage(String str, OutputStream os){ ? ? ? ? Random ran = new Random(); ? ? ? ? //創(chuàng)建圖片對(duì)象 ? ? ? ? BufferedImage img = new BufferedImage(100,40, BufferedImage.TYPE_INT_RGB); ? ? ? ? //獲取畫布 ? ? ? ? Graphics g = img.getGraphics(); ? ? ? ? //設(shè)置背景 ? ? ? ? g.setColor(Color.white); ? ? ? ? g.fillRect(0,0,100,40); ? ? ? ? //寫字 ? ? ? ? g.setColor(Color.black); ? ? ? ? g.setFont(new Font("微軟雅黑",Font.PLAIN,30)); ? ? ? ? g.drawString(str,10,40); ? ? ? ? //隨機(jī)三條線 ? ? ? ? g.drawLine(ran.nextInt(100),ran.nextInt(40), ? ? ? ? ? ? ? ? ran.nextInt(100),ran.nextInt(40)); ? ? ? ? g.drawLine(ran.nextInt(100),ran.nextInt(40), ? ? ? ? ? ? ? ? ran.nextInt(100),ran.nextInt(40)); ? ? ? ? g.drawLine(ran.nextInt(100),ran.nextInt(40), ? ? ? ? ? ? ? ? ran.nextInt(100),ran.nextInt(40)); ? ? ? ? // 4. 輸出結(jié)果 ? ? ? ? // 常見的壓縮格式:jpeg(有損壓縮), png(無損壓縮) ... ? ? ? ? try { ? ? ? ? ? ? ImageIO.write(img, "png", os); ? ? ? ? } catch (IOException e) { ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? } ? ? } ? ? }
regist.jsp
<%-- ? Created by IntelliJ IDEA. ? User: Administrator ? Date: 2018/10/14 ? Time: 15:43 ? To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> ? ? <title>注冊(cè)</title> ? ? <style> ? ? ?? ? ? ? ? img { cursor: pointer} ? ? </style> </head> <body> <form action="/regist" method="post"> ? ? <img src="/captcha.png" onclick="changeImg(this)"> ? ? 輸入驗(yàn)證碼:<input type="text" name="cap"> ? ? <input type="submit" value="提交"> </form> ? <script> ? ? ? function changeImg(img) { ? ? ? ? // 瀏覽器有一個(gè)緩存特性, ? ? ? ? // 第一次從服務(wù)器獲取圖片,瀏覽器第二次發(fā)送請(qǐng)求時(shí)發(fā)現(xiàn)地址沒有改變,就會(huì)使用第一次的圖片,而不會(huì)真正發(fā)送請(qǐng)求 ? ? ? ? // 為了讓瀏覽器每次都把請(qǐng)求發(fā)送給服務(wù)器,給一個(gè)時(shí)間參數(shù) ? ? ? ? img.src = "/captcha.png?t="+new Date().getTime(); // 給src賦一個(gè)新值,就會(huì)向新值的地址發(fā)送一次請(qǐng)求 ? ? } </script> </body> </html>
CaptchaServlet.java
package cn.seeker.controller; ? import cn.seeker.utils.CaptchaUtil; ? import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; ? @WebServlet(urlPatterns = "/captcha.png") public class CaptchaServlet extends HttpServlet { ? ? ? @Override ? ? protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ? ? ? ? ? response.setContentType("image/png"); ? ? ? ? //獲取隨機(jī)字符串 ? ? ? ? String random = CaptchaUtil.random(); ? ? ? ? //輸出圖片 ? ? ? ? CaptchaUtil.outputImage(random,response.getOutputStream()); ? ? ? ? //存入結(jié)果 ? ? ? ? request.getSession().setAttribute("res",CaptchaUtil.num); ? ? ? } ? ? }
registServlet.jsp
package cn.seeker.controller; ? import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; ? @WebServlet(urlPatterns = "/regist") public class registServlet extends HttpServlet { ? ? @Override ? ? protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ? ? ? ? String cap = req.getParameter("cap"); ? ? ? ? Integer res = (Integer)req.getSession().getAttribute("res"); ? ? ? ? if(Integer.parseInt(cap) == res) { ? ? ? ? ? ? // 填寫正確,注冊(cè)成功 ? ? ? ? ? ? req.getSession().removeAttribute("res"); ? ? ? ? ? ? System.out.println("注冊(cè)成功"); ? ? ? ? ? ? resp.sendRedirect("/index.jsp"); ? ? ? ? ? } else { ? ? ? ? ? ? req.setAttribute("error", "驗(yàn)證碼不正確"); ? ? ? ? ? ? req.getRequestDispatcher("/jsp/regist.jsp").forward(req,resp); ? ? ? ? } ? ? } }
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
MyBatis使用Zookeeper保存數(shù)據(jù)庫的配置可動(dòng)態(tài)刷新的實(shí)現(xiàn)代碼
這篇文章主要介紹了MyBatis使用Zookeeper保存數(shù)據(jù)庫的配置,可動(dòng)態(tài)刷新,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-08-0823種設(shè)計(jì)模式(12)java模版方法模式
這篇文章主要為大家詳細(xì)介紹了23種設(shè)計(jì)模式之java模版方法模式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11springboot實(shí)現(xiàn)rabbitmq的隊(duì)列初始化和綁定
這篇文章主要介紹了springboot實(shí)現(xiàn)rabbitmq的隊(duì)列初始化和綁定,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-10-10Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)之共享租車信息管理系統(tǒng)的實(shí)現(xiàn)
這是一個(gè)使用了java+Jsp+Servlet+Jdbc+Mysql開發(fā)的共享租車信息管理系統(tǒng),是一個(gè)畢業(yè)設(shè)計(jì)的實(shí)戰(zhàn)練習(xí),具有租車管理該有的所有功能,感興趣的朋友快來看看吧2022-02-02