上一篇文章的后续。主要是说明,验证码是如何实现的,以及cookie的验证,就是界面中"记住我"的功能。
思路:
- 既然我们要审核验证码是否正确,那么就要得到在页面中显示的验证码,在前一篇文章中显然是没有得到的。那么我们就可以在生成验证码的时候,直接获取。所以是在CheckCodeServlet中进行获取。
- 然后得到了验证码之后,因为我们验证的时候是在登录时进行,所以可以使用 会话(Session) 将验证码传出去,传值的方式有很多,那么为什么要使用会话(Session)? 后面会进行解释。
- 在登录的验证实现,要获取到用户输入的帐号,密码,验证码。然后与数据库及接收到的验证码进行匹配判断。
先看CheckCodeServlet中增加的传出部分。
//实例化StringBuilder对象对生成的验证码进行存储。
StringBuilder sb = new StringBuilder();
for(int i=0;i<4;i++){
int code = random.nextInt(10);
graphics.drawString(code+"", 15*i+20,25);
sb.append(code+"");
}
//运用会话可以传出去----用于验证的,只是为了实现的话不需要
request.getSession().setAttribute("imageCode", sb.toString());
登录验证代码:
package com.hym.servlet;
import java.io.IOException;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.hym.biz.UserBiz;
import com.hym.entity.User;
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private UserBiz userBiz = new UserBiz();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//取得在页面中输入的username,password;用作判断
String username = request.getParameter("username");
String password = request.getParameter("password");
//得到在页面中输入的验证码
String code = request.getParameter("code");
//接收在CheckCodeServlet中传过来的验证码
String imageCode = (String)request.getSession().getAttribute("imageCode");
//在服务层中进行逻辑上的判断输入的用户在数据库中是否存在。以及验证码是否正确。
if(userBiz.loginUser(new User(username,password))&&imageCode.equals(code)){
String remember = request.getParameter("remember");
//如果登录成功,判断"记住我"是否被勾选,被勾选后值为"on".如果被勾选,添加到cookie中。
if(remember!=null){
//处理中文乱码问题
username = URLEncoder.encode(username, "utf-8");
Cookie cookie = new Cookie("username",username);
//设置有效期
cookie.setMaxAge(60*60);
//设置cookie
response.addCookie(cookie);
}
//转发+request---实现数据回显的效果
request.setAttribute("msg", "登录成功,即将跳转到欢迎界面...");
request.getRequestDispatcher("welcome.jsp").forward(request, response);
//说明用户是存在的,用户名密码输入正确,但是验证码输入错误。
}else if(userBiz.loginUser(new User(username,password))){
request.setAttribute("msg", "登录失败,验证码错误,请重新输入....");
request.getRequestDispatcher("login.jsp").forward(request, response);
//全部输入错误
}else{
request.setAttribute("msg", "登录失败,请重新输入....");
request.getRequestDispatcher("login.jsp").forward(request, response);
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
-
讨论一下为什么要使用会话将值传出?这里介绍4种方式,并作比较:
//方式一、通过request对象;--->每次访问的request对象都不是一个对象; request.setAttribute("imgCode", sb.toString()); //方式二、设置全局变量---->问题,只能一个用户使用。 Utils.imgCode=sb.toString(); //方式三、通过context传参,在servlet中context就只有一份(与全局变量想过一致); request.getServletContext().setAttribute("imgCode", sb.toString()); //方式四、通过session传参:会话,一个用户访问任何页面都是同一个session,不同用户则拥有不同的session对象。每个用户有独立的session对象 request.getSession().setAttribute("imgCode", sb.toString()); 第一种方式每次访问的request对象都不是同一个对象,获取不到一致的验证码,甚至会为Null; 第二种和第三种本质上一致的,一个用户时不会出现问题,输入的验证码与传入的验证码一致,但是,当我们在不关闭页面的情况下,再打开一个时,原先界面中的验证码在后台会被改成新页面的,此时问题就出现了。 第四种方式,每个用户都是独立的,不同用户拥有不同的session对象,能保持一致。
添加cookie
也就三板斧就能简易实现:
1、实例化cookie对象;
2、设置有效期;
3、添加cookie
然后我们可以在登录界面的实现中,判断cookie是否存在,如果存在就直接进入,而不需要输入:
```
<body>
<%
Cookie[] cookies = request.getCookies();
if(cookies!=null){
for(Cookie cookie:cookies){
if("username".equals(cookie.getName())){
response.sendRedirect("welcome.jsp");
return;
}
}
}
%>
<%
/* String msg = (String) request.getSession().getAttribute("msg"); */
String msg = (String)request.getAttribute("msg");
%>
<%=(msg==null)?"":msg%>
<h2>欢迎来到登录界面...</h2>
<form action="LoginServlet" method="post">
UserName:<input type="text" name="username" /><br />
PassWord:<input type="password" name="password" /><br />
VerificationCode:<input type="text" name="code"/>
<img src="CheckCodeServlet"/><br/>
<input type="checkbox" name="remember"/>记住我<br/>
<input type="submit" value="提交" />
<input type="reset" value="重置" />
</form>