我们总是在登录微信,QQ或者其他一些网页的时候,都会出现一个验证码框,他们有的是数字的,有的是文字的,有的是混合的,各种各样的。
很好奇是怎么实现的。带着这样的疑问。
目录
首先创建一个javaWeb的工程
然后在之前创建的随机数方法里,进行循环答应,输出4个随机数
接下来我们需要定义图片的宽度和高度
BufferedImage对象是图片的缓冲流,用于GRB绘制对象,在内存操作过程中,将内存操作的每一个步骤绘制到内存里面存储起来。将缓冲流进行输出。产生一张图片。
//2.定义图片的高度和宽度
int width =120;
int height =25;
//建立bufferedImage对象,制定图片的长度和宽度以及色彩
BufferedImage bi =new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
//3.获取Graphics2D 绘制对象,开始绘制验证码
Graphics2D g =bi.createGraphics();
//4.设置文字的子图验证和大小
Font font =new Font("微软雅黑", Font.PLAIN, 20);
//5.设置字体的颜色
Color color =new Color(0,0,0);
//将颜色和字体放入
g.setFont(font);
g.setColor(color);
g.setBackground(new Color(226,226,226));//背景颜色
//开始绘制对象
g.clearRect(0, 0, width, height);
//绘制形状,获取距形对象
FontRenderContext context =g.getFontRenderContext();//文字读取上下文
Rectangle2D bounds =font.getStringBounds(code, context);//将生成的验证码放入
//计算文字的坐标和间距
double x =(width -bounds.getWidth())/2;
double y =(height -bounds.getHeight())/2;
double ascent =bounds.getY();
double baseY =y -ascent;
g.drawString(code, (int)x, (int)y);
//结束配置
g.dispose();
//将图片保存到制定地方,输出
try {
ImageIO.write(bi,"jpg",response.getOutputStream());
//刷新响应流
response.flushBuffer();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return code;//用于验证码的对比和存储
做完这些后,我们需要定义一个code.jsp页面
<%@ page import="com.kilig.code.CaptcahCode" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
//1:清空浏览器缓存,目的是为了清空浏览器的缓存,因为浏览器
//会对网站的资源文件和图像进行记忆存储,如果被浏览器加载过的图片就记忆起来,记忆以后
//文件就不会和服务器在交互,如果我们验证不清空的话可能会造成一个问题就是:验证刷新以后没有效果。
response.setHeader("pragma","no-cache");
response.setHeader("cache-control","no-cache");
response.setHeader("expires","0");
//2:调用编写的生成验证码的工具
String code = CaptcahCode.drawImage(response);
session.setAttribute("code",code);
//3:如何解决getOutputStream异常问题
out.clear();
out = pageContext.pushBody();
%>
然后在编制输出页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Java Verification Code</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
</head>
<body>
<img src="code.jsp" alt="" id="code">
<a href="javascript:void();" onclick="changeCode()">看不清,点我</a>
<script>
function changeCode(){
document.getElementById("code").src ="code.jsp?d="+new Date().getTime();
}
</script>
</body>
</html>
运行看效果:(每次刷新都不一样)
通过观察算数表达式的验证码图片我们得出:
public static String drawImageVerificate(HttpServletResponse response) throws IOException {
//定义验证码的宽度和高度
int width =100, height =30;
//在内存中创建图片
BufferedImage image =new BufferedImage(width,height, BufferedImage.TYPE_INT_RGB);
//创建图片的上下文
Graphics2D g =image.createGraphics();
//创建随机对象,此随机对象主要用于算数表达式的数字
Random random =new Random();
//设置背景
g.setColor(getRandomColor(240,250));
//设置字体
g.setFont(new Font("微软雅黑", Font.PLAIN,22));
//开始绘制
g.fillRect(0,0,width,height);
//干扰线的绘制 ,绘制线条到图片中
g.setColor(getRandomColor(180,230));
for (int i = 0; i <100 ; i++) {
int x =random.nextInt(width);
int y =random.nextInt(height);
int x1 =random.nextInt(60);
int y1 =random.nextInt(60);
g.drawLine(x, y,x1,y1);
}
//开始对算数验证码表达式进行拼接
int num1 =(int)(Math.random()*10+1);
int num2 =(int)(Math.random()*10+1);
int symbel =random.nextInt(3); //定义符号,产生一个[0,2]之间的随机整数
//记录符号
String symbelstr=null;
int result =0;
switch (symbel){
case 0 : symbelstr ="+";result =num1+num2; break;
case 1 : symbelstr ="-";result =num1-num2; break;
case 2 : symbelstr ="*";result =num1*num2; break;
}
//计算表达式
String calc =num1 + " "+ symbelstr +" "+ num2 +"=?";
//设置随机颜色
g.setColor(new Color(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());
return String.valueOf(result);
}catch (Exception ex){
ex.printStackTrace();
return null;
}
//return null;
}
kcaptcha实现技术 点击打开kaptcha的官网 网站需要VPN哦,需要VPN的可以私聊我。
Kaptcha是一个基于SimpleCaptcha的验证码开源项目。
1.在官网上下载Kaptcha的相关jar包。并且倒入到lib文件夹中
2.首先配置web.xml
3.然后创建一个页面的jsp index.jsp
启动服务
那么字母的定义,图片的宽度高度,干扰线的设置怎么去配置呢?
下面,从新引入到web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>Kaptcha</display-name>
<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>
</init-param>
<init-param>
<param-name>kaptcha.image.height</param-name>
<param-value>50</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.NoNoise</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Kaptcha</servlet-name>
<url-pattern>/kaptcha.jpg</url-pattern>
</servlet-mapping>
</web-app>
然后运行,进行参数的修改
具体其他参数的配置修改,我从官网上down下来
举个例子,比方说加入对文字内容的配置 ,要求只可以是123456789数字
让我们运行看一看,就会产生一个只有4位数字,并且宽度200,高度50的没有干扰线的验证码图片
不同方式的组合配置,会有不同的效果:
4.案例学习:
我们引入第三方的框架:jquery
增加一个时间搓,点击功能,当店家页面,实现刷新
在编写一个javascript的方法,看是否可以获取我们的用户输入的验证码
此时我们的客户端以及做好了,我们去完成我们的服务端的设计
在上面的介绍里,我们认识到,获取验证码框的函数是 kaptcha.session.key session key KAPTCHA_SESSION_KEY
如果用户输入的验证码和产生在服务器端的验证码一致,那么用户输入成功
equalsIgnoreCase(); 方法,不用区分大小写
LoginServlet
package com.kilig.code;
import java.io.IOException;
import java.io.PrintWriter;
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 javax.swing.text.StyleConstants.CharacterConstants;
import com.google.code.kaptcha.Constants;
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//设置编码
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
//需要获取浏览器的输出流对象
PrintWriter out =response.getWriter();
//获取用户传递过来的验证码
String code =request.getParameter("code");
//获取验证码框架产生的验证码
String sessionCode =(String)request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
System.out.println(code+"===="+sessionCode);
if(code != null && sessionCode != null) {
//如果用户输入的验证码和产生在服务器端的验证码一致,那么用户输入成功
if(code.equalsIgnoreCase(sessionCode)) {
System.out.println("Success");
}else {
System.out.println("Fail");
}
}else {
System.out.println("Fail");
}
//刷新和关闭
out.flush();
out.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
test.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>#code{height:25px;}</style>
</head>
<body>
<form action="submit.action">
<p>验证码:<input type="text",name="kaptcha", id="code" maxlength="4" placeholder="请输入验证码">
<img src="kaptcha.jpg" id ="changeCode"/></p>
<p><input type="button" value="登录" id="login"></p>
<div id="result"></div>
</form>
<script src="js/jquery-1.12.4.min.js"></script>
<script>
$(function(){
$("#changeCode").on("click",function(){
$(this).attr("src","kaptcha.jpg?d="+new Date().getTime());
})
//给登录按钮绑定登录事件
$("#login").on("click",function(){
//获取用户输入的验证码
var code =$("#code").val();
var params ={"code":code};
$.post("login",params,function(data){
if(data =="Success"){
$("#result").html("验证码输入正确!!");
}else{
$("#result").html("验证码输入有误,请重新输入。。。");
$("#code").val("").focus();
}
});
});
});
</script>
</body>
</html>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>Web</display-name>
<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>
</init-param>
<init-param>
<param-name>kaptcha.image.height</param-name>
<param-value>50</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.NoNoise</param-value>
</init-param>
<!-- "kcode"生成好的验证码 -->
<!--
<init-param>
<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>
<!-- 注册LoginServlet -->
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.kilig.code.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
</web-app>
文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib
文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang
文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些
文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器
文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距
文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器
文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn
文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios
文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql
文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...
文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120
文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数