1、session的作用
用户用浏览器访问web服务器时,会为每个用户创建一个session(会话),session在用户关闭浏览器之前都是有效的,所以我们可以在session中保存用户的一些信息,以供使用。这里我们用session保存用户的账号名称,以表示用户已经登录,可以直接访问后台页面。
2、cookie的作用
cookie是客户端保存的一些少量数据,每次用户通过浏览器访问web服务器时,cookie可以通过request一起传送至服务器端,这里我们使用cookie保存用户的账号密码,以便实现自动登录功能。
说明:实现过程分为两个页面
- login.jsp 是前台登录界面分别有账号、密码输入区,以及一个是否自动登录的复选框,一个选择保存时长的下拉列表框,如下图所示:
- mypage.jsp是登录后的显示界面,有一个注销按钮,以便用户登出。
3、流程
- 用户访问login.jsp进行第一次登录,对应的servlet将提交的用户名与密码和数据库中的记录进行匹配,如果:
- 匹配失败(要考虑用户名和密码为空的情况),则返回login.jsp进行再次登录,并且报告错误信息(记住提交URL参数中的中文需要用URLEncoder进行编码,不然会乱码)
- 匹配成功 (cookie是保存在客户端的,程序中进行配置之后一定需要用response.addCookies将cookie添加至response从而发回客户端浏览器)
- 如果选择了未自动登录,此时从request中取出原来的cookies,将有效时间设为0,表示不再进行自动登录。
- 如果选择了自动登录,那么就要创建两个新的cookie,一个保存username,一个保存passwd(安全的做法是用MD5等加密算法加密后保存),并根据选择的有效时间设置cookie的有效时间
- 之后用reque.getsession.setAttribute()设置username属性表示用户已经登录,最后将页面重定向至mypage.jsp
代码如下所示:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
String command= request.getParameter("command");
//这里是用户登录的界面,需要处理逻辑关系,考虑
if(command.equals("login"))
{
//1、没有输入用户名 2、用户名错误 3、密码错误
String username = request.getParameter("username");
String passwd = request.getParameter("passwd");
//如果未输入用户名
if(username.equals("")||passwd.equals(""))
{
System.out.println("未输入用户名");
String error_msg = "请输入用户名和密码";
String error =URLEncoder.encode(error_msg, "utf-8");
response.setCharacterEncoding("utf-8");
response.sendRedirect("/MyDBtest/login.jsp?error="+error);
}
//对用户名进行查询
else
{
String real_passwd = loginChecker.getPasswd(username);
//没有此用户
if(real_passwd.equals(""))
{
System.out.println("没有此用户");
String error_msg = "没有此用户,请重新输入用户名";
String error =URLEncoder.encode(error_msg, "utf-8");
response.setCharacterEncoding("utf-8");
response.sendRedirect("/MyDBtest/login.jsp?error="+error);
}
//查询成功 检查用户是否设置自动登录,如果是则发送cookies
else if(real_passwd.equals(passwd))
{
//设置session username属性表示用户已经登录
request.getSession().setAttribute("username", username);
//检查用户是否选择自动登录
//如果选择了自动登录,则需要保存cookies
if("on".equals(request.getParameter("autologin")))
{
int saveTime = Integer.parseInt(request.getParameter("maxage"));
saveTime =24*60*60*saveTime;
Cookie user_cookie = new Cookie("username", username);
Cookie passwd_cookie = new Cookie("passwd", passwd);
user_cookie.setMaxAge(saveTime);
passwd_cookie.setMaxAge(saveTime);
response.addCookie(user_cookie);
response.addCookie(passwd_cookie);
}
//如果没有选择自动登录
else
{
Cookie[] cookies = request.getCookies();
for(Cookie cookie:cookies)
{
System.out.println("删除 cookie");
if(cookie.getName().equals("username"))
{
cookie.setMaxAge(0);
response.addCookie(cookie); //添加生成的新的cookie
}
else if(cookie.getName().equals("passwd"))
{
cookie.setMaxAge(0);
response.addCookie(cookie); //添加生成的新的cookie
}
}
}
//重定向到后台界面
response.sendRedirect("/MyDBtest/mypage.jsp");
}
//密码错误
else {
System.out.println("密码错误");
String error_msg = "密码错误,请重新输入密码";
String error =URLEncoder.encode(error_msg, "utf-8");
response.setCharacterEncoding("utf-8");
response.sendRedirect("/MyDBtest/login.jsp?error="+error);
}
}
}
else if(command.equals("deleteCookies"))
{
//用户主动注销,那么不用再保存Cookies
Cookie[] cookies = request.getCookies();
for(Cookie cookie:cookies)
{
if(cookie.getName().equals("username"))
{
cookie.setMaxAge(0);
response.addCookie(cookie); //设置失效
}
else if(cookie.getName().equals("passwd"))
{
cookie.setMaxAge(0);
response.addCookie(cookie); //设置失效
}
}
//重定向到登录界面
request.getSession().removeAttribute("username");
response.sendRedirect("/MyDBtest/login.jsp");
}
}
}
- 对于访问mypage.jsp,步骤如下:
- 首先检查session是否有username属性,如果存在那么可以直接访问mypage.jsp,若不存在则进行下一步判断
- 取出request中的cookie(考虑为空的情况),取出用户名和密码,与数据库中记录进行匹配,若匹配成功,则设置session的username属性,表示已经登录成功,然后跳转至mypage.jsp
- 若与数据库匹配失败或者cookie为空,那么可将页面重定向至错误页面,提示用户进行登录后才能访问。
不难想到,应该为 mypage.jsp设置一个过滤器,每次访问该页面,先由过滤器完成上述流程,过滤器配置如下:
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>Filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/mypage.jsp</url-pattern>
</filter-mapping>
过滤器代码如下:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
// place your code here
//访问 mypage 页面前需要经过此过滤器
//System.out.println("进入到后台登录过滤器");
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse res = (HttpServletResponse)response;
//这里说明用户未登录,那么获取cookies并验证是否能登录
if(req.getSession().getAttribute("username")==null )
{
System.out.println("进入到后台登录过滤器");
Cookie[] cookies = req.getCookies();
String username=null;
String passwd=null;
if(cookies!=null)
{
for(Cookie cookie:cookies)
{
if(cookie.getName().equals("username"))
{
username = cookie.getValue();
}
else if(cookie.getName().equals("passwd"))
{
passwd =cookie.getValue();
}
}
}
if(username!=null&&passwd!=null)
{
//匹配数据中的用户名以及密码
//匹配成功则设置登录,否则退出登录
if(loginChecker.getPasswd(username).equals(passwd))
req.getSession().setAttribute("username", username);
}
}
// pass the request along the filter chain
chain.doFilter(req, res);
}
mypage.jsp页面还有一个注销按钮,用户注销后,servlet应该主动删除用户的cookie信息。