Java Web 七 会话技术 八 Cookie 九 Session

七 会话技术

打开浏览器,访问服务器中资源,关闭浏览器;这个过程就是会话

  • 分类
  * Cookie会话技术;浏览器会话技术
  * Session会话技术;服务器会话技术
  • 作用
解决ServletContext域对象、Request域对象存储数据所存在的问题

八 Cookie

8.1 Cookie介绍

网景公司发明。是浏览器的会话技术

  • Cookie的流程
  * 浏览器请求服务器,请求Demo01Servlet,创建一个Cookie对象,名称为cookie1
  
* 可以通过响应头Set-Cookie,携带cookie给浏览器进行保存
  * 浏览器再次请求服务器,请求Demo02Servlet,获取cookie1对象

------------------------------

8.2 Cookie的基本使用
  • 设置Cookie
//方式一(不推荐)
response.addHeader("set-cookie","msg=hellocoolie");
//方式二
Cookie cookie = new Cookie("msg","hellocookie");
response.addCookie(cookie);
  • 获取Cookie
开发步骤
    * 通过request对象获取所有的Cookie对象,存储到一个数组中
    * 遍历该数组,匹配Cookie名称
    * 如果匹配上,就知道了指定的Cookie对象
    * 如果匹配不上,就没有指定的Cookie对象
Cookie[] cookies = request.getCookies();
Cookie cookie = null;
for(Cookie sonCookie : cookies){
    if("msg".equals(sonCookie.getName())){
        cookie = sonCookie;
    }
}
if(null != cookie){
    System.out.println("name : "+msgCookie.getName() + " , value : "+ msgCookie.getValue());
}

------------------------------

8.3 Cookie的相关设置
  • 持久化设置
cookie的生命周期
    * 默认是随着浏览器的关闭而销毁
    
setMaxAge
    * 设置cookie的存活时长,cookie就可以不随着会话的关闭而销毁
    * 取值有三种:>0有效期,单位秒;=0浏览器关闭;<0内存存储,默认-1
  • 路径设置
默认情况下,Cookie对象会随着任何一个请求携带到服务器

setPath	设置Cookie的访问路径
	Cookie cookie = new Cookie("msg","helloworld");
    cookie.setPath("/day56/demo04");
    response.addCookie(cookie);

cookie对象只有访问路径包含"/day56/demo04",才会跟随请求携带到服务器

------------------------------

8.4 Cookie案例
8.4.1 记录上一次访问时间
需求:
   第一次访问,就直接打印当前时间
   不是第一次访问,就打印上一次的访问时间

开发步骤:
	获取对应的Cookie对象
    判断是否是第一次访问
    如果是第一次访问
      打印当前时间
      将当前时间存储到Cookie中
    如果不是第一次访问
      打印上一次访问时间
      将当前时间存储到Cookie中
  //判断是否是一次请求
  Cookie[] cookies = request.getCookies();
  Cookie cookie = null;//记录上一次的访问时间
  if (cookies != null && cookies.length != 0 ) {
      for (Cookie sonCookie : cookies) {
          if ("lastTime".equals(sonCookie.getName())) {
              cookie = sonCookie;
          }
      }
  }
  SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
  if (null == cookie) {
      //第一次访问 ,打印当前时间,并将创建Cookie对象,存储当前时间
  
      Date currentDate = new Date();
      System.out.println("第一次访问,时间为" + format.format(currentDate));
      cookie = new Cookie("lastTime",currentDate.getTime()+"");
  } else {
      //不是第一次访问,从cookie取出上一次的访问时间,并打印。获取当前时间,并存储cookie对象中
      long lastDateMills = Long.parseLong(cookie.getValue());
      Date lastDate = new Date(lastDateMills);
      //获取到了上一次的访问时间
      String lastTimeStr = format.format(lastDate);
      System.out.println("上一次访问,时间为" + lastTimeStr);
      //获取当前时间,并存储cookie对象中
      Date currentDate = new Date();
      //            cookie.setValue(currentDate.getTime()+"");
      cookie = new Cookie("lastTime",currentDate.getTime()+"");
  }  
  response.addCookie(cookie);
8.4.2 商品浏览记录
需求:
	浏览商品,将商品的浏览的记录起来,并显示!
  <!--页面代码 books.html-->
  <a href="/day56/history?id=0">西游记</a><br>
  <a href="/day56/history?id=1">红楼梦</a><br>
  <a href="/day56/history?id=2">水浒传</a><br>
  <a href="/day56/history?id=3">三国志</a><br>
/* * 获取history的Cookie对象
 * * 判断商品浏览记录是否为空
 * * 如果浏览记录没有
 * * * 创建Cookie,并将当前的商品记录到Cookie中
 * * 如果浏览记录有
 * * * 有当前的商品,不做任何处理
 * * * 没有当前商品,就需要将当前的商品拼接到已有记录中
*/
 @WebServlet(name = "HistoryServlet", urlPatterns = "/history")
public class HistoryServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    String id = request.getParameter("id");
    Cookie cookie = null;
    Cookie[] cookies = request.getCookies();
    if (null != cookies && 0 != cookies.length){
        for (Cookie sonCookie : cookies) {
            if ("history".equals(sonCookie.getName())) {
                cookie = sonCookie;
            }
        }
    }
  
    if (null == cookie) {
        //之前没有任何浏览记录 ,创建Cookie对象 ,并存储浏览记录(id)
        cookie = new Cookie("history",id);
    } else {
        //之前有一些浏览记录
        String historyStr = cookie.getValue();
        if (!historyStr.contains(id)) {
            //有一些记录,但是不包含当前浏览的商品;
            //将浏览商品拼接到已有浏览记录中
            //120
            //1-2-0
            historyStr += "-"+id;
            cookie.setValue(historyStr);
  
        } else {
            //有一些记录,包含当前浏览的商品 ,不做任何处理
        }
    }
    response.addCookie(cookie);
    //上述代码,已经完成了商品浏览记录功能,剩下就是要显示商品浏览记录
    response.sendRedirect(request.getContextPath()+ File.separator+"showHistory");
  }
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}
  /*
  * 显示商品浏览记录
  * * 获取history对应的Cookie对象
  * * 获取对应的商品浏览记录
  * * 判断是否有浏览记录
  * * 如果没有,就显示“没有浏览记录”
  * * 如果有,就显示处理浏览记录字符串
  */
@WebServlet(name = "ShowHistoryServlet", urlPatterns = "/show")
public class ShowHistoryServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		Cookie cookie = null;
  		Cookie[] cookies = request.getCookies();
  		if (null != cookies && 0 !=  cookies.length) {
      		for (Cookie sonCookie : cookies) {
          		if ("history".equals(sonCookie.getName())) {
             		 cookie = sonCookie;
          		}
     		 }
  		}
  		StringBuffer responseContent = new StringBuffer();//记录响应正文
  		if (null == cookie) {
		      //没有浏览记录
		      responseContent.append("<font color='red'>没有浏览记录</font>,");
		      responseContent.append("<a href='books.html'>浏览商品</a>");
		  } else {
		      //有浏览记录
		      //获取浏览记录 0-1-2-3
		      String[] bookNames = {"西游记","红楼梦","水浒传","三国志"};
		      String historyStr = cookie.getValue();
		      String[] historys = historyStr.split("-");
		      responseContent.append("您的浏览记录如下:<br>");
		      for (String history : historys) {
		          //history : 0 / 1 / 2 /3
		          String bookName = bookNames[Integer.parseInt(history)];
		          responseContent.append(bookName+"<br>");
		      }
		  }
		  response.setContentType("text/html;charset=utf-8");
		  response.getWriter().write(responseContent.toString());
		    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

------------------------------

8.5 CookieUtils工具类

获取指定名称的Cookie对象

public class CookieUtils {
    public static Cookie getCookie(Cookie[] cookies,String cookisName){
        if(cookies!=null&&cookies.length!=0){
            for(Cookie sonCookie:cookies){
                if(cookisName.equals(sonCookie.getName())){
                    return sonCookie;
                }
            }
        }
        return null;
    }
}

九 Session

9.1 Session基本使用

Cookie之所以叫做浏览器会话,原因是Cookie的数据存储到浏览器


Session之所以叫做服务器会话,原因是Session的数据存储到服务器

  • 执行流程
第一次请求Demo01Servlet时,根据request.getSession方法, 新建一个session对象
当第一次响应时,会将该session对象的id作为cookie头响应给浏览器保存
	set-cookie:JSESSIONID=4741C65CC84788A204E87EB870196EB0

第二次请求Demo01Servlet时,根据request.getSession方法,请求中会有cookie头
	Cookie:JSESSIONID=4741C65CC84788A204E87EB870196EB0

会根据该JSESSIONID去服务器中找有没有对应的session对象,如果有就直接用,没有就新建

------------------------------

9.2 Session相关配置

生命周期:session默认是有30分钟的存活时间,参考tomcat中的web.xml

      <session-config>
          <session-timeout>30</session-timeout>
      </session-config>
session和cookie是相关联的,cookie中存储了jsessionid,request.getSession方法会根据
	jsessionid去选择,到底是新建session对象,还是引用原来的session对象;

如果,将浏览器关闭了,就意味着cookie中存储的jsessionid就会销毁,
	对应request.getSession就会新建一个session对象,但是原来的session对象还存在
session只有两种情况会销毁
	调用了invalidate方法
	过了30分钟

------------------------------

9.3 session的基本使用
setAttribute	往session域对象中存储数据

getAttribute	从session域对象中获取数据

removeAttribute		把session域对象中的数据移除

------------------------------

9.4 session和request的区别
request是一次请求,session是一次会话,一次会话中包含多次请求

request中的数据(setAttritube)在重定向后失效,不同的request不能共享数据。
session中的数据无论是重定向还是转发,都能拿到。关闭浏览器失效

session默认有效期30分钟(打开浏览器,超过30分钟无操作,session失效)
重启Tomcat清空所有session

------------------------------

9.5 session和cookie的区别
session存在于服务端,可以存放任意类型的数据,依赖于cookie中的JSESSIONID
cookie存在于客户端,只能存放字符串
用户可能禁用浏览器的cookie,导致sessionid不能存储在浏览器cookie中
服务端就不能获取用户session信息
encodeRedirect方法,将用户的sessionid拼接到url后面
String url = resp.encodeRedirectURL("/admin/list");
resp.sendRedirect(url);

------------------------------

9.6 session案例
9.6.1 登录
  • UserDao
public class UserDaoImpl implements UserDao {
      @Override
      public User login(User inputUser) throws SQLException {
  //        ComboPooledDataSource就是连接池,连接池包含很多连接对象
  //        连接池作用就是减少连接的创建次数!
  //        第一个用户,登录,创建一个连接池,创建3个连接
  //        第二个用户,登录,创建一个连接池,创建3个连接
  //        应该只让连接池创建一次!!后面复用就OK了!!
          QueryRunner queryRunner = new QueryRunner(JDBCUtils.getDataSource());
          User existUser = queryRunner.query(
                  "select * from tb_user where username = ? and password = ?",
                  new BeanHandler<User>(User.class),
                  inputUser.getUsername(),
                  inputUser.getPassword());`在这里插入代码片`  
          return existUser;
      }
  }
  • LoginServlet
@WebServlet(name = "LoginServlet",urlPatterns = "/login")
  public class LoginServlet extends HttpServlet {
  
      private UserDao userDao = new UserDaoImpl();
  
      protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          String username = request.getParameter("username");
          String password = request.getParameter("password");
          User inputUser = new User();
          inputUser.setUsername(username);
          inputUser.setPassword(password);
          try {
              User existUser = userDao.login(inputUser);
              System.out.println(existUser);
              //判断登录成功
              if (null == existUser) {
                  //登录失败,请求转发,跳转到登录页面
                  request.getRequestDispatcher("/login.html").forward(request,response);
              } else {
                  //登录成功,重定向,跳转到显示用户信息
                  //存储existUser
                  //request : 跳转到首页,使用了重定向,会有一个新的请求
                  //servletContext : 如果存储到ServletContext,就意味着所有人都可以拿到你的用户信息!
                  //cookie : 如果存储到cookie中,就是存储到浏览器 , 不安全! cookie中是无法存储中文及一些特殊符号!!
                  //session : 数据存储到服务器!!
                  request.getSession().setAttribute("existUser",existUser);
                  response.sendRedirect("/day57/showIndex");
  
              }
  
          } catch (SQLException throwables) {
              throwables.printStackTrace();
          }
      }
  
      protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          doPost(request,response);
      }
  }
  • ShowIndexServlet
  @WebServlet(name = "ShowIndexServlet" ,urlPatterns = "/showIndex")
  public class ShowIndexServlet extends HttpServlet {
      protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          response.setContentType("text/html;charset=utf-8");
          User existUser = (User) request.getSession().getAttribute("existUser");
          if (null != existUser) {
              //在登录状态
              response.getWriter().write("欢迎回来,"+existUser.getUsername());
          } else {
              //不在登录状态
              //方式一:提示下,未登录
  //            response.getWriter().write("您还没有登录,<a href='/day57/login.html'>请登录</a>");
              //方式二:跳转到登录页面
              response.sendRedirect("/day57/login.html");
              //看需求,选择方式一还是方式二
              //登录状态权限管理!!
          }
      }
  
      protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          doPost(request, response);
      }
  }

第三方jar包,必须放到WEB-INF文件夹中
登录失败使用请求转发、登录成功使用重定向

---------------

9.6.2 随机验证码
  • 显示验证码
	创建图片对象
	画背景
	画边框
  	画干扰线
  	产生四位随机数,存储到session
  	画四位随机数
  	将图片响应到浏览器
      protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          int width = 60;//定义图片宽度
          int height = 32;//定义图片高度
          //创建图片对象
          BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
          //创建画笔对象
          Graphics g = image.getGraphics();
          //设置背景颜色
          g.setColor(new Color(0xDCDCDC));
          g.fillRect(0, 0, width, height);//实心矩形
          //设置边框
          g.setColor(Color.black);
          g.drawRect(0, 0, width - 1, height - 1);//空心矩形
  
          Random rdm = new Random();
          //画干扰椭圆
          for (int i = 0; i < 50; i++) {
              int x = rdm.nextInt(width);
              int y = rdm.nextInt(height);
              g.drawOval(x, y, 0, 0);
          }
          //产生随机字符串
          String hash1 = Integer.toHexString(rdm.nextInt());
          //生成四位随机验证码
          String capstr = hash1.substring(0, 4);
          //将产生的验证码存储到session域中,方便以后进行验证码校验!
          request.getSession().setAttribute("existCode", capstr);
          System.out.println(capstr);
          g.setColor(new Color(0, 100, 0));
          g.setFont(new Font("Candara", Font.BOLD, 24));
          g.drawString(capstr, 8, 24);
          g.dispose();
          //将图片响应到浏览器
          response.setContentType("image/jpeg");
          OutputStream strm = response.getOutputStream();
          ImageIO.write(image, "jpeg", strm);
          strm.close();
      }
  • 校验验证码
  //获取输入的验证码
  String validateCode = request.getParameter("validateCode");
  //将输入的验证码和产生的随机验证码进行校验
  String existCode = (String) request.getSession().getAttribute("existCode");
  if (validateCode.equals(existCode)) {
      //校验通过,完成登录功能
  } else {
      //校验不通过,跳转到登录页面
  
  }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值