JavaWeb - 验证码

简介: JavaWeb - 验证码
  1. 为什么要学习验证码?
    1、可以防止恶意破解密码、刷票、论坛灌水。
    2、有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试。
    3、实际上用验证码是现在很多网站通行的方式,我们利用比较简易的方式实现了这个功能。
  2. 验证码实现的方式
    1、字母数字混合验证码
importjavax.imageio.ImageIO;
importjavax.servlet.http.HttpServletResponse;
importjava.awt.*;
importjava.awt.font.FontRenderContext;
importjava.awt.geom.Rectangle2D;
importjava.awt.image.BufferedImage;
importjava.util.Random;
/*** 此方法用户产生随机数-字母和数字* @return*/privatestaticcharrandomChar(){
//1:定义验证需要的字母和数字Stringstring="QWERTYUIOPASDFGHJKLZXCVBNM0123456789";
//2:定义随机对象Randomrandom=newRandom();
returnstring.charAt(random.nextInt(string.length()));
}
/*** 字母数字混合验证码* @param response* @return*/publicstaticStringdrawImage(HttpServletResponseresponse){
//1:定义以字符串的拼接的StringBuilderStringBuilderbuilder=newStringBuilder();
//准备产生4个字符串的随机数for(inti=0;i<4;i++){
builder.append(randomChar());
    }
Stringcode=builder.toString();
//2:定义图片的宽度和高度intwidth=70;
intheight=25;
//简历bufferedImage对象,制定图片的长度和宽度以及色彩BufferedImagebi=newBufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR);
//3:获取到 Graphics2D 绘制对象,开始绘制验证码Graphics2Dg=bi.createGraphics();
//4:设置文字的字体和大小Fontfont=newFont("微软雅黑",Font.PLAIN,20);
//设置字体的颜色Colorcolor=newColor(0,0,0);
//设置字体g.setFont(font);
//设置颜色g.setColor(color);
//设置背景g.setBackground(newColor(226,226,240));
//开始绘制对象g.clearRect(0,0,width,height);
//绘制形状,获取矩形对象FontRenderContextcontext=g.getFontRenderContext();
Rectangle2Dbounds=font.getStringBounds(code,context);
//计算文件的坐标和间距doublex= (width-bounds.getWidth())/2;
doubley= (height-bounds.getHeight())/2;
doubleascent=bounds.getY();
doublebaseY=y-ascent;
g.drawString(code,(int)x,(int)baseY);
//结束绘制g.dispose();
try {
ImageIO.write(bi,"jpg",response.getOutputStream());
//刷新响应流response.flushBuffer();
    }catch(Exceptionex){
ex.printStackTrace();
    }
returncode;
}
// code.jsp<%@pageimport="com.imooc.code.CaptcahCode"%><%@pagecontentType="text/html;charset=UTF-8"language="java"%><%// 清空浏览器缓存,目的是为了清空浏览器的缓存,因为浏览器会对网站的资源文件和图像进行记忆存储,// 如果被浏览器加载过的图片就记忆起来,记忆以后,// 文件就不会和服务器在交互,如果我们验证不清空的话可能会造成一个问题就是:验证刷新以后没有效果。response.setHeader("pragma","no-cache");
response.setHeader("cache-control","no-cache");
response.setHeader("expires","0");
//2:调用编写的生成验证码的工具Stringcode=CaptcahCode.drawImage(response);
session.setAttribute("code",code);
//3:如何解决getOutputStream异常问题out.clear();
out=pageContext.pushBody();
%>
// index.jsp<%@pagelanguage="java"import="java.util.*"pageEncoding="UTF-8"%><!DOCTYPEHTML><html><head><title>java验证码</title><metahttp-equiv="pragma"content="no-cache"><metahttp-equiv="cache-control"content="no-cache"><metahttp-equiv="expires"content="0"></head><body><imgsrc="code.jsp"alt=""id="code"><ahref="javascript:void(0);"onclick="changeCode()">看不清?点我</a><script>functionchangeCode() {
document.getElementById("code").src="code.jsp?d="+newDate().getTime();
         }
</script></body></html>

2、算术验证码

image.png

image.png

importjavax.imageio.ImageIO;
importjavax.servlet.http.HttpServletResponse;
importjava.awt.*;
importjava.awt.font.FontRenderContext;
importjava.awt.geom.Rectangle2D;
importjava.awt.image.BufferedImage;
importjava.util.Random;
/*** 范围随机颜色* @param fc* @param bc* @return*/publicstaticColorgetRandomColor(intfc,intbc){
//利用随机数Randomrandom=newRandom();
//随机颜色,了解颜色-Color(red,green,blue).rgb三元色 0-255if(fc>255)fc=255;
if(bc>255)bc=255;
intr=fc+random.nextInt(bc-fc);
intg=fc+random.nextInt(bc-fc);
intb=fc+random.nextInt(bc-fc);
returnnewColor(r,g,b);
}
/*** 算术表达式验证码** 1:干扰线的产生* 2: 范围随机颜色,随机数** @param response* @return*/publicstaticStringdrawImageVerificate(HttpServletResponseresponse){
//定义验证码的宽度和高度intwidth=100,height=30;
//在内存中创建图片BufferedImageimage=newBufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
//创建图片的上下文Graphics2Dg=image.createGraphics();
//产生随机对象,此随机对象主要用于算术表达式的数字Randomrandom=newRandom();
//设置背景g.setColor(getRandomColor(240,250));
//设置字体g.setFont(newFont("微软雅黑", Font.PLAIN,22));
//开始绘制g.fillRect(0,0,width,height);
//干扰线的绘制,绘制线条到图片中g.setColor(getRandomColor(180,230));
for(inti=0;i<10;i++){
intx=random.nextInt(width);
inty=random.nextInt(height);
intx1=random.nextInt(60);
inty1=random.nextInt(60);
g.drawLine(x,y,x1,y1);
    }
//开始进行对算术验证码表达式的拼接intnum1= (int)(Math.random()*10+1);
intnum2= (int)(Math.random()*10+1);
intfuhao=random.nextInt(3);//产生一个[0,2]之间的随机整数//记录符号Stringfuhaostr=null;
intresult=0;
switch (fuhao){
case0 : fuhaostr="+";result=num1+num2;break;
case1: fuhaostr="-";result=num1-num2;break;
case2 : fuhaostr="*";result=num1*num2;break;
//case 3 : fuhaostr = "/";result = num1 / num2;break;    }
//拼接算术表达式,用户图片显示。Stringcalc=num1+" "+fuhaostr+" "+num2+" = ?";
//设置随机颜色g.setColor(newColor(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
//绘制表达式g.drawString(calc,5,25);
//结束绘制g.dispose();
try {
//输出图片到页面ImageIO.write(image,"JPEG",response.getOutputStream());
returnString.valueOf(result);
    }catch (Exceptionex){
ex.printStackTrace();
returnnull;
    }
}
// code.jsp<%@pageimport="com.imooc.code.CaptcahCode"%><%@pagecontentType="text/html;charset=UTF-8"language="java"%><%// 清空浏览器缓存,目的是为了清空浏览器的缓存,因为浏览器会对网站的资源文件和图像进行记忆存储,// 如果被浏览器加载过的图片就记忆起来,记忆以后,// 文件就不会和服务器在交互,如果我们验证不清空的话可能会造成一个问题就是:验证刷新以后没有效果。response.setHeader("pragma","no-cache");
response.setHeader("cache-control","no-cache");
response.setHeader("expires","0");
//2:调用编写的生成验证码的工具Stringcode=CaptcahCode.drawImageVerificate(response);
session.setAttribute("code",code);
//3:如何解决getOutputStream异常问题out.clear();
out=pageContext.pushBody();
%>
// index.jsp<%@pagelanguage="java"import="java.util.*"pageEncoding="UTF-8"%><!DOCTYPEHTML><html><head><title>java验证码</title><metahttp-equiv="pragma"content="no-cache"><metahttp-equiv="cache-control"content="no-cache"><metahttp-equiv="expires"content="0"></head><body><imgsrc="code.jsp"alt=""id="code"><ahref="javascript:void(0);"onclick="changeCode()">看不清?点我</a><script>functionchangeCode() {
document.getElementById("code").src="code.jsp?d="+newDate().getTime();
         }
</script></body></html>

3、kcaptcha

// index.jsp<%@pagecontentType="text/html;charset=UTF-8"language="java"%><html><head><title>关于验证码框架之---Kaptcha</title></head><body><formaction="submit.action"><inputtype="text"name="kaptcha"value=""/><imgsrc="http://localhost:8080/imooccode/kaptcha.jpg"/></form></body></html>
// web.xml<?xmlversion="1.0"encoding="UTF-8"?><web-appxmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"version="3.1"><!--关于kaptcha验证码的配置--><!--<servlet><servlet-name>Kaptcha</servlet-name><servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class></servlet><servlet-mapping><servlet-name>Kaptcha</servlet-name><url-pattern>/kaptcha.jpg</url-pattern></servlet-mapping>--><servlet><servlet-name>Kaptcha</servlet-name><servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class><init-param><param-name>kaptcha.border</param-name><param-value>no</param-value></init-param><init-param><param-name>kaptcha.image.width</param-name><param-value>100</param-value></init-param><init-param><param-name>kaptcha.image.height</param-name><param-value>40</param-value></init-param><init-param><param-name>kaptcha.textproducer.font.size</param-name><param-value>28</param-value></init-param><init-param><param-name>kaptcha.textproducer.char.string</param-name><param-value>qwertyuiopasdfghjklzxcvbnm123456789</param-value></init-param><init-param><param-name>kaptcha.textproducer.char.length</param-name><param-value>4</param-value></init-param><init-param><param-name>kaptcha.noise.impl</param-name><param-value>com.google.code.kaptcha.impl.DefaultNoise</param-value></init-param><init-param><param-name>kaptcha.obscurificator.impl</param-name><param-value>com.google.code.kaptcha.impl.FishEyeGimpy</param-value></init-param><init-param><!--session.setAttribute("kcode",生成好的验证码)--><param-name>kaptcha.session.key</param-name><param-value>kcode</param-value></init-param></servlet><servlet-mapping><servlet-name>Kaptcha</servlet-name><url-pattern>/kaptcha.jpg</url-pattern></servlet-mapping><servlet><servlet-name>LoginServlet</servlet-name><servlet-class>com.imooc.code.LoginServlet</servlet-class></servlet><servlet-mapping><servlet-name>LoginServlet</servlet-name><url-pattern>/login</url-pattern></servlet-mapping>--></web-app>
// 配置详情.txtKaptcha是一个基于SimpleCaptcha的验证码开源项目。官网地址:http://code.google.com/p/kaptcha/kaptcha的使用比较方便,只需添加jar包依赖之后简单地配置就可以使用了。kaptcha所有配置都可以通过web.xml来完成,如果你的项目中使用了SpringMVC,那么则有另外的一种方式来实现。一、简单的jsp-servlet项目1.添加jar包依赖如果你使用maven来统一管理jar包,则在工程的pom.xml中添加dependencyXml代码收藏代码<!--kaptcha--><dependency><groupId>com.google.code.kaptcha</groupId><artifactId>kaptcha</artifactId><version>2.3.2</version></dependency>如果是非maven管理的项目,则直接在官网下载kaptcha的jar包,然后添加到项目lib库中,下载地址:http://code.google.com/p/kaptcha/downloads/list2.配置web.xml上面说了,kaptcha都是在web.xml中配置,我们必须在web.xml中配置kaptcha的servlet,具体如下:Xml代码收藏代码<servlet><servlet-name>Kaptcha</servlet-name><servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class></servlet><servlet-mapping><servlet-name>Kaptcha</servlet-name><url-pattern>/kaptcha.jpg</url-pattern></servlet-mapping>其中servlet的url-pattern可以自定义。kaptcha所有的参数都有默认的配置,如果我们不显示配置的话,会采取默认的配置。如果要显示配置kaptcha,在配置kaptcha对应的Servlet时,在init-param增加响应的参数配置即可。示例如下:Xml代码收藏代码<servlet><servlet-name>Kaptcha</servlet-name><servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class><init-param><param-name>kaptcha.image.width</param-name><param-value>200</param-value><description>Widthinpixelsofthekaptchaimage.</description></init-param><init-param><param-name>kaptcha.image.height</param-name><param-value>50</param-value><description>Heightinpixelsofthekaptchaimage.</description></init-param><init-param><param-name>kaptcha.textproducer.char.length</param-name><param-value>4</param-value><description>Thenumberofcharacterstodisplay.</description></init-param><init-param><param-name>kaptcha.noise.impl</param-name><param-value>com.google.code.kaptcha.impl.NoNoise</param-value><description>Thenoiseproducer.</description></init-param></servlet>具体的配置参数参见:http://code.google.com/p/kaptcha/wiki/ConfigParametersConstant描述默认值kaptcha.border图片边框,合法值:yes , noyeskaptcha.border.color边框颜色,合法值:r,g,b (andoptionalalpha) 或者white,black,blue.   blackkaptcha.border.thickness边框厚度,合法值:>01kaptcha.image.width图片宽200kaptcha.image.height图片高50kaptcha.producer.impl图片实现类com.google.code.kaptcha.impl.DefaultKaptchakaptcha.textproducer.impl文本实现类com.google.code.kaptcha.text.impl.DefaultTextCreatorkaptcha.textproducer.char.string文本集合,验证码值从此集合中获取abcde2345678gfynmnpwxkaptcha.textproducer.char.length验证码长度5kaptcha.textproducer.font.names字体Arial, Courierkaptcha.textproducer.font.size字体大小40pxkaptcha.textproducer.font.color字体颜色,合法值:r,g,b或者white,black,blue.   blackkaptcha.textproducer.char.space文字间隔2kaptcha.noise.impl干扰实现类com.google.code.kaptcha.impl.DefaultNoisekaptcha.noise.color干扰颜色,合法值:r,g,b或者white,black,blue.    blackkaptcha.obscurificator.impl图片样式:水纹com.google.code.kaptcha.impl.WaterRipple鱼眼com.google.code.kaptcha.impl.FishEyeGimpy阴影com.google.code.kaptcha.impl.ShadowGimpycom.google.code.kaptcha.impl.WaterRipplekaptcha.background.impl背景实现类com.google.code.kaptcha.impl.DefaultBackgroundkaptcha.background.clear.from背景颜色渐变,开始颜色lightgreykaptcha.background.clear.to背景颜色渐变,结束颜色whitekaptcha.word.impl文字渲染器com.google.code.kaptcha.text.impl.DefaultWordRendererkaptcha.session.keysessionkeyKAPTCHA_SESSION_KEYkaptcha.session.datesessiondateKAPTCHA_SESSION_DATE3.页面调用Html代码收藏代码<formaction="submit.action"><inputtype="text"name="kaptcha"value=""/><imgsrc="kaptcha.jpg"/></form>4.在submit的action方法中进行验证码校验Java代码收藏代码//从session中取出servlet生成的验证码text值StringkaptchaExpected= (String)request.getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
//获取用户页面输入的验证码StringkaptchaReceived=request.getParameter("kaptcha");
//校验验证码是否正确if (kaptchaReceived==null||!kaptchaReceived.equalsIgnoreCase(kaptchaExpected)){
setError("kaptcha", "Invalid validation code.");
}
注:确保JDK设置了-Djava.awt.headless=true5.实现页面验证码刷新Html代码收藏代码<imgsrc="kaptcha.jpg"width="200"id="kaptchaImage"title="看不清,点击换一张"/><scripttype="text/javascript">$(function() {
$('#kaptchaImage').click(function() {$(this).attr('src','kaptcha.jpg?'+Math.floor(Math.random() *100));});
    });
</script><br/><small>看不清,点击换一张</small>

4、jcaptcha

  1. 了解验证码功能的实现与原理

image.pngimage.pngimage.pngimage.png

4.kcaptcha 应用版(在2的kcaptcha的基础上

image.png

// test.jsp<%--CreatedbyIntelliJIDEA.
User: AdministratorDate: 2017/9/8Time: 21:10TochangethistemplateuseFile|Settings|FileTemplates.
--%><%@pagecontentType="text/html;charset=UTF-8"language="java"%><html><head><title>登录</title><style>#code{height:30px;}</style></head><body><formaction="submit.action"><p><inputtype="text"name="kaptcha"id="code"value=""maxlength="4"placeholder="请输入验证码"/><imgsrc="http://localhost:8080/imooccode/kaptcha.jpg"id="changecode"/></p><p><inputtype="button"id="login"value="登录"></p><divid="result"></div></form><scriptsrc="js/jquery-1.12.4.min.js"type="text/javascript"></script><script>$(function(){
$("#changecode").on("click",function(){
$(this).attr("src","http://localhost:8080/imooccode/kaptcha.jpg?d="+newDate().getTime());
        });
//给登录按钮绑定点击事件$("#login").on("click",function(){
//获取用户输入的验证码varcode=$("#code").val();
//alert(code);varparams= {"code":code};
$.post("http://localhost:8080/imooccode/login",params,function(data){
//                if(data=="fail"){//                     alert("验证码输入有误!");//                }if(data=="success"){
$("#result").html("验证码输入正确");
                }else{
$("#result").html("验证码输入有误,请重新输入...");
$("#code").val("").focus();
                }
            });
        });
    })
</script></body></html>
packagecom.imooc.code;
importcom.google.code.kaptcha.Constants;
importjavax.servlet.ServletException;
importjavax.servlet.annotation.WebServlet;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importjava.io.IOException;
importjava.io.PrintWriter;
publicclassLoginServletextendsHttpServlet {
publicvoiddoPost(HttpServletRequestrequest, HttpServletResponseresponse) throwsServletException, IOException {
//设置编码request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
//获取浏览器输出流对象PrintWriterout=response.getWriter();
//获取用户传递过来的验证码Stringcode=request.getParameter("code");
//获取验证码框架产生的验证码(会话中存储的验证码)StringsessionCode= (String)request.getSession().getAttribute("kcode");
if(code!=null&sessionCode!=null) {
//如果用户输入的验证码和产生在服务器端的验证码一致,那么就告诉用户输入正确if (code.equalsIgnoreCase(sessionCode)) {
//登录逻辑、注册逻辑等相关的业务操作out.print("success");
            } else {
out.print("fail");
            }
        }
out.flush();
out.close();
    }
publicvoiddoGet(HttpServletRequestrequest, HttpServletResponseresponse) throwsServletException, IOException {
this.doPost(request,response);
    }
}

5.待更新...

相关实践学习
函数计算部署PuLID for FLUX人像写真实现智能换颜效果
只需一张图片,生成程序员专属写真!本次实验在函数计算中内置PuLID for FLUX,您可以通过函数计算+Serverless应用中心一键部署Flux模型,快速体验超写实图像生成的魅力。
从 0 入门函数计算
在函数计算的架构中,开发者只需要编写业务代码,并监控业务运行情况就可以了。这将开发者从繁重的运维工作中解放出来,将精力投入到更有意义的开发任务上。
目录
相关文章
|
7月前
|
JavaScript Java 大数据
基于JavaWeb的销售管理系统设计系统
本系统基于Java、MySQL、Spring Boot与Vue.js技术,构建高效、可扩展的销售管理平台,实现客户、订单、数据可视化等全流程自动化管理,提升企业运营效率与决策能力。
|
7月前
|
存储 前端开发 Java
【JAVA】Java 项目实战之 Java Web 在线商城项目开发实战指南
本文介绍基于Java Web的在线商城技术方案与实现,涵盖三层架构设计、MySQL数据库建模及核心功能开发。通过Spring MVC + MyBatis + Thymeleaf实现商品展示、购物车等模块,提供完整代码示例,助力掌握Java Web项目实战技能。(238字)
834 0
|
7月前
|
安全 Java API
Java Web 在线商城项目最新技术实操指南帮助开发者高效完成商城项目开发
本项目基于Spring Boot 3.2与Vue 3构建现代化在线商城,涵盖技术选型、核心功能实现、安全控制与容器化部署,助开发者掌握最新Java Web全栈开发实践。
697 1
|
8月前
|
前端开发 Java 数据库
Java 项目实战从入门到精通 :Java Web 在线商城项目开发指南
本文介绍了一个基于Java Web的在线商城项目,涵盖技术方案与应用实例。项目采用Spring、Spring MVC和MyBatis框架,结合MySQL数据库,实现商品展示、购物车、用户注册登录等核心功能。通过Spring Boot快速搭建项目结构,使用JPA进行数据持久化,并通过Thymeleaf模板展示页面。项目结构清晰,适合Java Web初学者学习与拓展。
536 1
|
8月前
|
JavaScript Java 微服务
现代化 Java Web 在线商城项目技术方案与实战开发流程及核心功能实现详解
本项目基于Spring Boot 3与Vue 3构建现代化在线商城系统,采用微服务架构,整合Spring Cloud、Redis、MySQL等技术,涵盖用户认证、商品管理、购物车功能,并支持Docker容器化部署与Kubernetes编排。提供完整CI/CD流程,助力高效开发与扩展。
908 64
|
9月前
|
缓存 NoSQL Java
Java Web 从入门到精通之苍穹外卖项目实战技巧
本项目为JavaWeb综合实战案例——苍穹外卖系统,涵盖Spring Boot 3、Spring Cloud Alibaba、Vue 3等主流技术栈,涉及用户认证、订单处理、Redis缓存、分布式事务、系统监控及Docker部署等核心功能,助你掌握企业级项目开发全流程。
927 0
|
9月前
|
SQL 前端开发 Java
JavaWeb 学习日记案例详解及 javaweb 完整项目案例实战指南
本文介绍了一个基于Spring Boot的JavaWeb企业员工管理系统完整案例,涵盖部门管理、员工管理、登录、异常处理、事务管理及AOP等核心功能实现,结合CSDN相关技术文章,提供详细技术方案与应用实例,适合JavaWeb开发者学习与参考。
551 0
|
9月前
|
安全 JavaScript Java
java Web 项目完整案例实操指南包含从搭建到部署的详细步骤及热门长尾关键词解析的实操指南
本项目为一个完整的JavaWeb应用案例,采用Spring Boot 3、Vue 3、MySQL、Redis等最新技术栈,涵盖前后端分离架构设计、RESTful API开发、JWT安全认证、Docker容器化部署等内容,适合掌握企业级Web项目全流程开发与部署。
751 0
|
缓存 Java 应用服务中间件
java语言后台管理若依框架-登录提示404-接口异常-系统接口404异常如何处理-登录验证码不显示prod-api/captchaImage 404 (Not Found) 如何处理-解决方案优雅草卓伊凡
java语言后台管理若依框架-登录提示404-接口异常-系统接口404异常如何处理-登录验证码不显示prod-api/captchaImage 404 (Not Found) 如何处理-解决方案优雅草卓伊凡
4081 5
|
网络协议 Java Shell
java spring 项目若依框架启动失败,启动不了服务提示端口8080占用escription: Web server failed to start. Port 8080 was already in use. Action: Identify and stop the process that’s listening on port 8080 or configure this application to listen on another port-优雅草卓伊凡解决方案
java spring 项目若依框架启动失败,启动不了服务提示端口8080占用escription: Web server failed to start. Port 8080 was already in use. Action: Identify and stop the process that’s listening on port 8080 or configure this application to listen on another port-优雅草卓伊凡解决方案
976 7
下一篇
开通oss服务