经过登录案例之添加验证码案例的分析,大家对本案例的功能有了一定的了解,下面我们就来实现该案例,点击此处 可以下载本案例源代码,具体如下:
(1)本案例是在HttpSession第二例中的案例的基础上完成的,案例的其他功能详情可以参考HttpSession第二例;下面我们对Example22中的login.jsp页面稍作修改,如例1-1所示:
例1-1 login.jsp
<body> <%– 本页面提供登录表单,还要显示错误信息 –%> <h1>登录</h1> <% /* 读取名为uname的Cookie! 如果为空显示:"" 如果不为空显示:Cookie的值 */ String uname = ""; Cookie[] cs = request.getCookies();//获取请求中所有的cookie if(cs != null) {// 如果存在cookie for(Cookie c : cs) {//循环遍历所有的cookie if("uname".equals(c.getName())) {//查找名为uname的cookie uname = c.getValue();//获取这个cookie的值,给uname这个变量 } } } %> <% String message = ""; String msg = (String)request.getAttribute("msg");//获取request域中的名为msg的属性 if(msg != null) { message = msg; } %> <font color="red"><b><%=message %> </b></font> <form action="/Example22/LoginServlet" method="post"> <%– 把cookie中的用户名显示到用户名文本框中 –%> 用户名:<input type="text" name="username" value="<%=uname%>"/><br/> 密 码:<input type="password" name="password"/><br/> 验证码:<input type="text" name="verifyCode" size="3"/> <img id="img" src="/Example22/VerifyCodeServlet"/><br> <input type="submit" value="登录"/> </form> </body> |
在例1-1中,新添加了一个表单项:验证码,并且还有一个<img>标签,该标签的src属性值为“/Example22/VerifyCodeServlet”,后面我们会新建一个名为VerifyCodeSerlvet的Servlet类。
(2)在该应用下,新建一个package,名为cn.itcast.utils,然后将生成验证码图片中的VerifyCode类放在该package下。
(3)在该应用下,新建一个Servlet类,名称为VerifyCodeServlet,其在web.xml文件中配置的访问路径为“/VerifyCodeServlet”,主要代码如例1-2所示:
例1-2 VerifyCodeServlet.java
public class VerifyCodeServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* * 1. 生成图片 * 2. 保存图片上的文本到session域中 * 3. 把图片响应给客户端 */ VerifyCode vc = new VerifyCode(); BufferedImage image = vc.getImage(); request.getSession().setAttribute("session_vcode", vc.getText());//保存图片上的文本到session域 VerifyCode.output(image, response.getOutputStream()); } } |
在例1-2中,首先通过VerifyCode帮助类获取一张图片,然后将图片上的验证码保存在session域中,最后调用VerifyCode类的output()方法,将图片保存在输出流中,由于我们要将图片输出在浏览器端,所以这里的输出流是response.getOutputStream()字节输出流,通过这个流就可以将图片显示在浏览器端。
(4)将Example22发布到服务器中,然后开启服务器,然后在浏览器端访问:http://localhost:8080/Example22/login.jsp,并使用HttpWatch工具查看请求信息,如图1-1所示:
图1-1 访问login.jsp
由图1-1可知,我们在访问login.jsp时,浏览器一共发送了两个请求:一个是请求login.jsp,另一个是请求VerifyCodeServlet。
(5)浏览器的显示结果如图1-2所示:
图1-2 浏览器显示结果
图1-2中,生成的验证码图片中的值为“28hS”。
(6)下面对应用中的LoginServlet进行修改,这里只给出添加的代码,如例1-3所示:
例1-3 LoginServlet.java
/* * 校验验证码 * 1. 从session中获取正确的验证码 * 2. 从表单中获取用户填写的验证码 * 3. 进行比较! * 4. 如果相同,向下运行,否则保存错误信息到request域,转发到login.jsp */ String sessionCode=(String)request.getSession(). getAttribute("session_vcode"); String paramCode = request.getParameter("verifyCode"); if(!paramCode.equalsIgnoreCase(sessionCode)) { request.setAttribute("msg", "验证码错误!"); request.getRequestDispatcher("/session/login.jsp"). forward(request, response); return; } |
例1-3中,if语句中转发代码之后要使用“return”关键字结束方法的执行,如果不使用return关键字,那么该方法还会继续执行下去,如果后面有重定向或转发语句那么就会抛异常。
(7)重新启动服务器,在浏览器端再次访问login.jsp,然后输入用户名:zhagnsan,密码:123,如图1-3所示:
图1-3 浏览器显示结果
图1-3中,正确的验证码是“QYCe”,而输入的验证码是“qyce”,由于在LoginServlet中验证码忽略大小写,所以这样写也是正确的。
(8)点击图1-3中的“登录”按钮,浏览器显示结果如图1-4所示:
图1-4 浏览器显示结果
(9)再次访问login.jsp,用户名和密码输入的仍然是zhangsan,123,如图1-5所示:
图1-5 浏览器显示结果
(10)点击图1-5中的“登录”按钮,浏览器显示结果如图1-6所示:
图1-6 浏览器显示结果
验证码不正确,那么就转发到login.jsp,并在浏览器端打印“验证码错误”。
(11)在浏览器端访问login.jsp页面,再次访问该页面时,使用HttpWatch工具获取请求信息,如图1-7所示:
图1-7 请求信息
图1-7中,访问login.jsp页面,服务器响应200状态码,但是访问VerifyCodeServlet走的是浏览器的缓存,也就是说页面中的验证码不改变。
(12)为了解决以上问题,我们对login.jsp页面做些修改,在验证码后面添加一个超链接“换一张”,并添加一段javascript代码,如例1-4所示:
<script type="text/javascript"> function _change() { /* 1. 得到img元素 2. 修改其src为/day11_3/VerifyCodeServlet */ var imgEle = document.getElementById("img"); imgEle.src = "/Example22/VerifyCodeServlet?a=" + new Date().getTime(); } </script> … … <a href="javascript:_change()">换一张</a> |
例1-4中,当点击超链接“换一张”时就执行_change()函数,该函数首先获得id为“img”的标签,如果设置该标签的src属性的值为“/Example22/VerifyCodeServlet”,那么还是会出现图1-7所示结果,所以我们在该路径后面添加了一个请求参数a,该参数的值是当前时间的毫秒值,那么a的值就会随着时间的改变而改变,因此每次点击超链接,服务器就认为是一次新的请求,从而做出响应。
(13)在浏览器段再次访问login.jsp,如图1-8所示:
图1-8 浏览器显示结果
(14)点击图1-8中的“换一张”,浏览器显示结果如图1-9所示:
图1-9浏览器显示结果
图1-8与图1-9中的验证码不相同,表明代码有效。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/253196.html