一、session
1、基本使用
会话
在整个会话周期中任何servlet或者jsp页面都可以到会话的数据
设置数据
//将登录用户的信息存入到session中 HttpSession //获得session对象 HttpSession session = req.getSession(); session.setAttribute("loginUser", loginUser);
获取数据
在servlet中获取
HttpSession session = req.getSession(); session.getAttribute("loginUser");
在jsp页面获取
${sessionScope.loginUser.uname} 上面的代码实质就是下面两行代码 Users user = (Users)session.getAttribute("loginUser"); String uname = user.getUname();
2、登录的功能
每个用户必须登录以后才可以访问其他功能。
目前编写的登录没有实现这个功能。
需要添加代码来完成这个功能。
怎么完成?
登录完成后,在session存储登录用户的信息。没有登录成功,则session中没有存储登录用户信息
在所有的servlet中判断登录用户是否存在,如果存在允许访问,如果不存在,不允许访问。
a、在登录时将登录用户的信息存入session
private void login(HttpServletRequest req, HttpServletResponse resp) throws IOException { //1、获得表单中提交的数据 String uname = req.getParameter("uname"); String upwd = req.getParameter("upwd"); Users user = new Users(); user.setUname(uname); user.setUpwd(upwd); //2、调用service方法 Users loginUser=us.login(user); //3、跳转 if(loginUser!=null) { //将登录用户的信息存入到session中 HttpSession //获得session对象 HttpSession session = req.getSession(); session.setAttribute("loginUser", loginUser); resp.sendRedirect("emp.do"); }else { resp.sendRedirect("login.html"); } }
b、在所有要控制的servlet中添加控制代码
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); //1、获得session对象 HttpSession session = req.getSession(); //2、获得session中的登录用户 Users loginUser = (Users) session.getAttribute("loginUser"); //3、判断登录用户是否存在,来决定你是否登录成功 if(loginUser!=null) { String method = req.getParameter("method"); if(method==null||method.equals("")) { method="query"; } switch(method) { // case "list": // list(req,resp); // break; case "query": query(req,resp); break; } }else { resp.sendRedirect("login.html"); } }
c、如果用户使用完毕,需要退出登录
登录用户${sessionScope.loginUser.uname }<a href="exit.do">退出登录</a>
ExitServlet.java
package com.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ExitServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //销毁session req.getSession().invalidate(); resp.sendRedirect("login.html"); } }
二、过滤器
1、问题:
上面代码实现了session控制访问的功能,但是要在每个需要控制访问的servlet中编写判断代码,工作量太大,而且不好维护。
解决方案就是使用filter过滤器
2、编写过滤器类
LoginFilter.java
实现过滤器接口Filter javax.servlet.Filter
package com.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import com.entity.Users; public class LoginFilter implements Filter { @Override public void destroy() { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { //过滤器 //编写代码 //arg0 request //arg1 response //将ServletRequest的arg0转成HttpServletRequest //(HttpServletRequest) arg0 说明arg0的类型大于HttpServletRequest类型 //public abstract interface javax.servlet.http.HttpServletRequest extends javax.servlet.ServletRequest HttpServletRequest req = (HttpServletRequest) arg0; //获得session HttpSession session = req.getSession(); //获得登录用户信息 Users loginUser = (Users) session.getAttribute("loginUser"); if(loginUser!=null) { //放行,也就是继续运行用户请求的内容 arg2.doFilter(arg0, arg1); }else { HttpServletResponse resp = (HttpServletResponse) arg1; resp.sendRedirect("login.html"); } } @Override public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub } }
3、过滤器也需要在web.xml中配置
<filter> <filter-name>loginFilter</filter-name> <filter-class>com.filter.LoginFilter</filter-class> </filter> <filter-mapping> <filter-name>loginFilter</filter-name> <!-- 地址栏中所有的*.do请求都会被当前filter拦截 --> <url-pattern>*.do</url-pattern> </filter-mapping>
4、过滤器就可以将所有*.do请求过滤
实际上就是在执行目标servlet中的代码前,执行过滤器代码
在其他servlet中就不用编写session控制访问的代码
实现字符集过滤器
a、编写过滤器
package com.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class EncodingFilter implements Filter { private String encoding; @Override public void destroy() { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { request.setCharacterEncoding(encoding); response.setCharacterEncoding(encoding); //上面两行代码在所有被过滤的servlet中都加上了 chain.doFilter(request, response); } @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub encoding = filterConfig.getInitParameter("encoding"); } }
b、配置过滤器
<filter> <filter-name>ef</filter-name> <filter-class>com.filter.EncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>ef</filter-name> <!-- 地址栏中所有的*.do请求都会被当前filter拦截 --> <url-pattern>*.do</url-pattern> </filter-mapping>
三、Cookie
1、自动登录
自动登录多久,设置cookie失效时间
a、登录完成时,在UsersServlet中将登录成功的用户名和密码存入cookied中
//设定cookie的失效时间 String timeStr = req.getParameter("time"); //如果没有传参,则默认不保存 int t = 0; if(timeStr!=null) { t = Integer.parseInt(timeStr); } //将登录户名名称和密码存到cookie中 //在服务器端生成cookie //cookie只能存入字符串,想要存入的信息有多个值,需要拼接存入 Cookie cookie = new Cookie("loginUser", loginUser.getUname()+":"+loginUser.getUpwd()); //设定失效时间 cookie.setMaxAge(t); resp.addCookie(cookie);
package com.servlet; import java.io.IOException; 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 javax.servlet.http.HttpSession; import com..entity.Users; import com.service.UserService; import com.service.UserServiceImpl; public class UsersServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // req.setCharacterEncoding("utf-8"); // resp.setCharacterEncoding("utf-8"); String method = req.getParameter("method"); switch (method) { case "login": login(req,resp); break; default: break; } } UserService us = new UserServiceImpl(); private void login(HttpServletRequest req, HttpServletResponse resp) throws IOException { //1、获得表单中提交的数据 String uname = req.getParameter("uname"); String upwd = req.getParameter("upwd"); Users user = new Users(); user.setUname(uname); user.setUpwd(upwd); //2、调用service方法 Users loginUser=us.login(user); //3、跳转 if(loginUser!=null) { //设定cookie的失效时间 String timeStr = req.getParameter("time"); int t = 0; if(timeStr!=null) { t = Integer.parseInt(timeStr); } //将登录户名名称和密码存到cookie中 //在服务器端生成cookie //cookie只能存入字符串,想要存入的信息有多个值,需要拼接存入 Cookie cookie = new Cookie("loginUser", loginUser.getUname()+":"+loginUser.getUpwd()); cookie.setMaxAge(t); resp.addCookie(cookie); //将登录用户的信息存入到session中 HttpSession //获得session对象 HttpSession session = req.getSession(); //设定session的失效时间,参数为失效的秒数 // session.setMaxInactiveInterval(5); session.setAttribute("loginUser", loginUser); resp.sendRedirect("emp.do"); }else { resp.sendRedirect("login.html"); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
b、因为登录界面需要使用java代码,所以将html转成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> <link rel="stylesheet" href="css/bootstrap.min.css" /> <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script> <script type="text/javascript" src="js/bootstrap.min.js" ></script> </head> <body> <% //实现自动登录 Cookie[] cookies = request.getCookies(); for(int i=0;i<cookies.length;i++){ Cookie c = cookies[i]; //判断cookie中是否存在登录用户信息,如果存在,则直接登录 if(c.getName().equals("loginUser")){ if(c.getValue()!=null&&!c.getValue().equals("")){ String[] strs = c.getValue().split(":"); //在重定向的时候直接将cookie中的登录用户信息分解传入登录servlet response.sendRedirect("users.do?method=login&uname="+strs[0]+"&upwd="+strs[1]); } } } %> <div class="panel panel-info col-md-6 col-md-offset-3"> <div class="panel-heading h2"> 登录界面 </div> <div class="panel-body"> <form class="form-horizontal" action="users.do?method=login" method="post"> <div class="form-group"> <label class="col-md-2 control-label" for="uname">用户名</label> <div class="col-md-10"> <input type="text" name="uname" id="uname" class="form-control" > </div> </div> <div class="form-group"> <label class="col-md-2 control-label" for="upwd">密码</label> <div class="col-md-10"> <input type="password" name="upwd" id="upwd" class="form-control" > </div> </div> <select name="time"> <option value="0">不保存</option> <option value="10">保存一天</option> <option value="30">保存一周</option> <option value="300">保存一月</option> </select> <button class="btn btn-success btn-block">登录</button> </form> </div> </div> </body> </html>
将所有跳转到login.html代码转成login.jsp
在LoginFilter和ExitServlet中修改