目录
第1关:使用Servlet生成验证码
任务描述
本关任务:使用servlet
生成验证码。
相关知识
验证码在我们登陆、注册网站,火车票买票的时候经常会见到的,为什么要有验证码呢?可能很多人都会有这个疑问。
但是作为开发者,可能我们更多的就会关注怎么生成验证码了。
要了解如何生成验证码,我们首先要知道什么是验证码,网站为什么需要它。
为什么要有验证码,什么是验证码
我们经常需要在网站或者应用程序中填写验证码,不过作为用户而言其实我们一点都不喜欢验证码,因为有时候老容易填错。
为什么这个影响用户体验的东西还是一直存在呢?
肯定是有道理的。
一个网站除了我们人操作电脑可以登录之外,使用JavaScript
代码和一些脚本语言也是可以登录的,但是我们开发网站是给人用的而不是给机器使用的,我们想象一个网站如果没有验证码,我们只需要编写一段脚本就可以无限次数的登陆某个网站,这样无数次的尝试就可以暴力破解用户的密码,如果是注册行为那就会给网站制造很多垃圾信息,这个就会对该网站造成极大的资源浪费,严重的可能会让这个网站崩溃,所以就有了验证码。
说白了,验证码就是用来判断是人在操作还是机器在操作。
如何使用Servlet生成验证码
在Java
中我们可以在Web
项目中使用Servlet
来生成验证码,流程是:前端请求验证码servlet
对应的地址,后端servlet
收到请求,生成一串字符作为验证码,存入到Session
中,最后将验证码作为一张图片返回给前端。前端填写了验证码提交到服务器来验证。
我们看一个示例,你也可以根据这个示例在右侧编辑器中一步一步实现验证码的功能。
项目和servlet
已经创建好了,我们首先在web.xml
文件中注册servlet
。
如下:
在servlet
的doGet()
方法中编写代码实现生成图片验证码:
分为如下步骤:
定义图像数据缓冲区(
BufferedImage
);创建图片对象;
创建绘制工具(
Graphics
);生成随机数,存入到
session
中;使用
Graphics
绘制图形;将验证码通过图像输出流(
ImageIO
)输出到客户端;最后输入验证码地址即可访问单验证码。
具体代码如下:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 使用验证码的步骤
// 定义图片的宽高
int height = 20;
int width = 60;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 绘图工具
Graphics graphics = image.getGraphics();
// 绘制矩形
graphics.setColor(getRandColor());
// 绘制矩形背景 前两个参数 是 x y的坐标
graphics.fillRect(0, 0, width, height);
// 设置文字的颜色 为白色
graphics.setColor(Color.WHITE);
String yzm = "";
// 生成四个随机数字并且画在图片上
for (int i = 1; i <= 4; i++) {
// 生成随机数字并且显示到页面上
int number = new Random().nextInt(10);
yzm += number;
graphics.drawString(number + "", 10 * i, 10);
}
// 将验证码放入Httpsession中
HttpSession session = req.getSession();
session.setAttribute("sessionYzm", yzm);
// 将验证码图片输出到客户端
ImageIO.write(image, "jpg", resp.getOutputStream());
}
// 获取随机颜色
private Color getRandColor() {
int red = new Random().nextInt(255);
int green = new Random().nextInt(255);
int blue = new Random().nextInt(255);
return new Color(red, green, blue);
}
编程要求
web.xml
中的代码已经添加,按照上述步骤编写servlet
代码,点击测评即可。
效果图:
测试说明
因为需要部署服务器,并且运行测试代码,所以评测时间较长,需要30
秒左右。
评测成功截图:
只要按照它的代码打一遍即可,注意不要打错了
第2关:用户登录时校验验证码是否正确
任务描述
本关任务:编写程序验证验证码是否正确。
相关知识
上一关我们已经学习如何生成验证码了,为了完成一整套的验证码使用流程我们还需要知道如何验证用户提交的验证码是否正确。
登录功能
我们经常在登录注册的时候填写验证码,本关我们就来实现登录功能。
首先我们来理解验证码校验的基本流程:
上图展示了一个用户填写验证码的基本流程,用户打开网页显示服务端生成的验证码,点击“看不清楚”标签可以重新生成,这个时候会从新请求服务端数据,服务端用Session
来保存验证码信息。
当用户点击确认按钮的时候,我们就需要对用户通过表单提交的验证码进行校验了,这个时候服务端获取Session
保存的验证码信息和用户提交的验证码数据进行校验如果两者一致则校验通过。
这就是一个完整的验证码流程了。
我们可以将验证码的流程总结为:前端表单登陆 => 后端获取到验证码校验 => 前端收到后端的响应。
借下来我们来实现这个过程。
前端实现
我们创建一个登录表单,代码如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<form action="loginServlet">
用户名:
<input type="text" name="username">
<br>
密 码:
<input type="text" name="password">
<br>
验证码:
<input type="text" name="verifycode" id="yzm">
<!-- src填servlet的地址就能显示网络上的图片 -->
<a href="javascript:reload()"><img id="yzmImg" src="code"/> </a>
<br>
<input type="submit" value="提交">
</form>
</body>
<script type="text/javascript">
//重新加载验证码
function reload() {
var img = document.getElementById("yzmImg");
img.src = "code?" + new Date().getTime();
}
</script>
</html>
效果如下:
后端校验
前端页面写好之后我们就可以验证在后端编写代码来验证,表单传递过来的参数是否正确了。
步骤如下:
接收用户传递的参数:
username,password,verifycode
;判断验证码是否正确;
如果验证码正确则判断用户名和密码是否正确。否则提示客户端验证码错误;
用户名密码正确,回传给客户端“登录成功”。
校验验证码的核心代码如下:
编程要求
好了,该你啦,使用本关所学内容,完成登录的校验,具体要求如下:
首先实现验证码校验的功能,当验证码填写错误的时候,给前端返回数据“验证码错误”;
当用户名为
admin
,密码为admin123
时可以登录成功,返回“登录成功”,其他情况返回“登录失败”;前端页面已经编写完成,你需要编写的是后端代码。
测试说明
本次实训使用的是junit+cactus
框架进行测试,所有测试集通过即算通关。
本关评测需要自己修改一些代码
截图如下:
第3关:使用Kaptcha组件生成验证码
任务描述
本关任务:使用Kaptcha
组件生成验证码,并校验验证码是否正确。
相关知识
之前两关我们已经了解了验证码的制作流程,不过我们在开发中一般不会去自己从零开始编写验证码,而是会使用到开源的组件,本关我们就来使用Kaptcha
来生成验证码,并且编写一个页面校验用户的验证码是否输入正确。
Kaptcha 组件的使用
先来看要实现的效果:
首先制作用户填写验证码的页面captchacode.jsp
<script type="text/javascript">
function reloadCode() {
var date = new Date().getTime();
document.getElementById("code").src = "<%=request.getContextPath() %>/imageKaptcha?d="+date;
}
</script>
<form action="checkCaptcha.jsp" method = "post">
<img alt="验证码" src="imageKaptcha" id = "code"><a href = "javascript:reloadCode();">看不清</a>
<input type = "text" name = "captcha">
<input type = "submit" value = "submit">
</form>
接着我们写一个检查验证码输入是否正确的类checkCaptchaServlet.java
request.setCha\fracterEncoding("utf-8");
// 获取Kaptcha jar包里面的KAPTCHA_SESSION_KEY
String trueCaptcha = (String)session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
String inputCaptcha = request.getParameter("captcha");
if(trueCaptcha.toLowerCase().equals(inputCaptcha.toLowerCase())) {
out.write("验证码输入正确");
} else {
out.write("验证码输入错误");
}
然后配置好web.xml
就ok
了。下面我们来看看怎么配置web.xml
<servlet>
<servlet-name>myCaptcha</servlet-name>
<!-- jar中的 KaptchaServlet的路径-->
<servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
</servlet>
<!--配置kaptcha 校验验证码是否正确的 servlet-->
<servlet>
<servlet-name>CheckCaptcha</servlet-name>
<servlet-class>com.servlet.CheckCaptchaServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myCaptcha</servlet-name>
<!-- 对于index.jsp中img的src -->
<url-pattern>/imageKaptcha</url-pattern>
</servlet-mapping>
<!--第三关:配置kaptcha 校验验证码的 servlet-->
<servlet-mapping>
<servlet-name>CheckCaptcha</servlet-name>
<url-pattern>/checkCaptcha</url-pattern>
</servlet-mapping>
做完上述步骤之后,运行项目,打开网页,即可查看验证码
输入正确的验证码点击submit
:
经过上述步骤我们就使用Kaptcha
组件生成验证码了。
扩展:Kaptcha
还有很多其他的设置可以实现图片边框,边框颜色,中文验证码等操作,限于篇幅在这里就不在赘述。
编程要求
好了,到你啦,来使用Kaptcha
生成验证码并校验输入的验证码是否正确吧。
补全
captchacode.jsp
,实现验证码表单的页面效果;补全
CheckCaptchaServlet
,实现验证码的校验功能,验证码正确返回:验证码输入正确
,否则返回:验证码输入错误
。
这里需要自己修改代码
截图如下:
captchacode.jsp
checkCaptchaServlet.java