zoukankan      html  css  js  c++  java
  • Cookie:Session,ServletContext

    学习 Cookie 之后,解决了不用发送请求的数据共享问题。Cookie 是浏览器端的数据存储技术,本节课重点介绍另外一门重要的数据存储技术,session 技术。

    Session 学习

    问题:

    Request 对象解决了一次请求内的不同 Servlet 的数据共享问题,那么一个用户的不同请求的处理需要使用相同的数据怎么办呢?

    解决:

    使用session 技术。

    原理:

    用户使用浏览器第一次向服务器发送请求,服务器在接受到请求后,调用对应的 Servlet 进行处理。在处理过程中会给用户创建一个session 对象,用来存储用户请求处理相关的公共数据,并将此 session 对象的 JSESSIONID 以 Cookie 的形式存储在浏览器中 (临时存储,浏览器关闭即失效)。用户在发起第二次请求及后续请求时,请求信息中会附带JSESSIONID,服务器在接收到请求后, 调用对应的Servlet 进行请求处理,同时根据 JSESSIONID 返回其对应的session 对象。

    特点:

    Session 技术是依赖Cookie 技术的服务器端的数据存储技术。

    由服务器进行创建

    每个用户独立拥有一个session

    默认存储时间为 30 分钟作用:

    解决了一个用户的不同请求的数据共享问题。

    使用:

    创建Session 对象

    存储数据到session 对象获取session 对象

    获取数据从session 对象

    如果获取session 中不存在的数据返回null。

    注意:

    只要不关闭浏览器,并且 session 不失效的情况下,同一个用户的任意请求在项目的任意Servlet 中获取到的都是同一个session 对象。

    作用域: 一次会话

    Servlet Session

    HTTP 是一种"无状态"协议,这意味着每次客户端检索网页时,客户端打开一个单独的连接到 Web 服务器,服务器会自动不保留之前客户端请求的任何记录。

    三种方式来维持 Web 客户端和 Web 服务器之间的 session 会话

    1、Cookies

    2、隐藏的表单字段

    3、URL 重写

    HttpSession 对象

    除了上述的三种方式,Servlet 还提供了 HttpSession 接口,该接口提供了一种跨多个页面请求或访问网站时识别用户以及存储有关用户信息的方式。

    Servlet 容器使用这个接口来创建一个 HTTP 客户端和 HTTP 服务器之间的 session 会话。会话持续一个指定的时间段,跨多个连接或页面请求。

    通过调用 HttpServletRequest 的公共方法 getSession() 来获取 HttpSession 对象,如下所示:

     

    HttpSession session = request.getSession();

    你需要在向客户端发送任何文档内容之前调用 request.getSession()。下面总结了 HttpSession 对象中可用的几个重要的方法:

    方法 & 描述

    public Object getAttribute(String name)

    该方法返回在该 session 会话中具有指定名称的对象,如果没有指定名称的对象,则返回 null。

    public Enumeration getAttributeNames()

    该方法返回 String 对象的枚举,String 对象包含所有绑定到该 session 会话的对象的名称。

    public long getCreationTime()

    该方法返回该 session 会话被创建的时间,自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。

    public String getId()

    该方法返回一个包含分配给该 session 会话的唯一标识符的字符串。

    public long getLastAccessedTime()

    该方法返回客户端最后一次发送与该 session 会话相关的请求的时间自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。

    public int getMaxInactiveInterval()

    该方法返回 Servlet 容器在客户端访问时保持 session 会话打开的最大时间间隔,以秒为单位。

    public void invalidate()

    该方法指示该 session 会话无效,并解除绑定到它上面的任何对象。

    public boolean isNew()

    如果客户端还不知道该 session 会话,或者如果客户选择不参入该 session 会话,则该方法返回 true。

    public void removeAttribute(String name)

    该方法将从该 session 会话移除指定名称的对象。

    public void setAttribute(String name, Object value)

    该方法使用指定的名称绑定一个对象到该 session 会话。

    public void setMaxInactiveInterval(int interval)

    该方法在 Servlet 容器指示该 session 会话无效之前,指定客户端请求之间的时间,以秒为单位。

    删除 Session 会话数据

    1、移除一个特定的属性:您可以调用 public void removeAttribute(String name) 方法来删除与特定的键相关联的值。

    2、删除整个 session 会话:您可以调用 public void invalidate() 方法来丢弃整个 session 会话。

    3设置 session 会话过期时间:您可以调用 public void setMaxInactiveInterval(int interval) 方法来单独设置 session 会话超时。

    web.xml 配置

    使用的是 Tomcat,除了上述方法,您还可以在 web.xml 文件中配置 session 会话超时,如下所示:

     <session-config>

        <session-timeout>15</session-timeout>

      </session-config>

    上面实例中的超时时间是以分钟为单位,将覆盖 Tomcat 中默认的 30 分钟超时时间。

    在一个 Servlet 中的 getMaxInactiveInterval() 方法会返回 session 会话的超时时间,以秒为单位。所以,如果在 web.xml 中配置 session 会话超时时间为 15 分钟,那么 getMaxInactiveInterval() 会返回 900。

    
    
    package cn.sxt;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    /**
     * Servlet implementation class lianxi2
     */
    @WebServlet("/lianxi2")
    public class lianxi2 extends HttpServlet {
        private static final long serialVersionUID = 1L;
           
        /**
         * @see HttpServlet#HttpServlet()
         */
        public lianxi2() {
            super();
            // TODO Auto-generated constructor stub
        }
    
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            response.getWriter().append("Served at: ").append(request.getContextPath());
           //创建Session 对象
            HttpSession session = request.getSession();
           //存储数据到session 对象(临时,关闭浏览器后就清空)
            session.setAttribute("name", "cxk");
            session.setAttribute("age", "20");
            //响应给浏览器
            response.getWriter().println("secc");
        
        
        
        
        
        
        
        
        }
    
        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    }
    
    
    


    package
    cn.sxt; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /** * Servlet implementation class lianxi1 */ @WebServlet("/lianxi1") public class lianxi1 extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public lianxi1() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.getWriter().append("Served at: ").append(request.getContextPath()); //同一浏览器(同一用户)Session 对象 HttpSession session = request.getSession(); //该方法返回在该 session 会话中具有指定名称的对象 response.getWriter().println(" "+session.getAttribute("name")+" "); response.getWriter().println(" "+session.getAttribute("age")+" "); response.getWriter().println(" "+session.getCreationTime()+" "); //该方法返回一个包含分配给该 session 会话的唯一标识符的字符串。 response.getWriter().println(" "+session.getId()+" "); //该方法返回客户端最后一次发送与该 session 会话相关的请求的时间自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。 response.getWriter().println(" "+session.getLastAccessedTime()+" "); //该方法返回 Servlet 容器在客户端访问时保持 session 会话打开的最大时间间隔,以秒为单位。 response.getWriter().println(" "+session.getMaxInactiveInterval()+" "); //该方法将从该 session 会话移除指定名称的对象。 session.removeAttribute("age"); //该方法在 Servlet 容器指示该 session 会话无效之前,指定客户端请求之间的时间,以秒为单位。 session.setMaxInactiveInterval(10); //更改属性值 session.setAttribute("name", "ycy"); response.getWriter().println(" "+session.getAttribute("name")+" "); response.getWriter().println(" "+session.getAttribute("age")+" "); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }

    通过前面知识点的学习,我们对于请求的处理已经可以说比较灵活了,但是还不够。我们再介绍重要的对象ServletContext 对象

    ServletContext 对象

    问题:

    Request 解决了一次请求内的数据共享问题,session 解决了用户不同请求的数据共享问题,那么不同的用户的数据共享该怎么办呢?

     

    解决:

    使用ServletContext 对象

    作用:

    解决了不同用户的数据共享问题

    原理:

    ServletContext 对象由服务器进行创建,一个项目只有一个对象。不管在项目的任意位置进行获取得到的都是同一个对象,那么不同用户发起的请求获取到的也就是同一个对象了,该对象由用户共同拥有

    特点:

    服务器进行创建

    用户共享

    一个项目只有一个生命周期:

    服务器启动到服务器关闭

     

    作用域:

    项目内

    怎么使用ServletContext

    使用ServletContext:

    (1) 如何得到ServletContext对象

    this.getServletContext();

    (2) 你可以把它想象成一张表,这个和Session非常相似:每一行就是一个属性,如下:

    添加属性:setAttribute(String name, Object obj);

    得到值:getAttribute(String name),这个方法返回Object

    删除属性:removeAttribute(String name)

    
    
    package cn.sxt;
    
    import java.io.IOException;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    /**
     * Servlet implementation class lianxi2
     */
    @WebServlet("/lianxi2")
    public class lianxi2 extends HttpServlet {
        private static final long serialVersionUID = 1L;
           
        /**
         * @see HttpServlet#HttpServlet()
         */
        public lianxi2() {
            super();
            // TODO Auto-generated constructor stub
        }
    
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            response.getWriter().append("Served at: ").append(request.getContextPath());
           //1/获取servletcontent对象
            ServletContext servletContext = this.getServletContext();
            //2/设置servletcontext属性
            servletContext.setAttribute("host", "localhost");
            response.getWriter().println("
    sucess set servlet Context");
            
            //用户的浏览次数
            if (servletContext.getAttribute("num")==null) {
            servletContext.setAttribute("num", 1);
        } else {
          int i = (int)servletContext.getAttribute("num")+1;
          servletContext.setAttribute("num",i );
        }
            response.getWriter().println("
    "+servletContext.getAttribute("host"));
            response.getWriter().println("web vistied num:"+ servletContext.getAttribute("num"));
            
        
        
        
        }
    
        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    }
    
    
    

    package
    cn.sxt; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /** * Servlet implementation class lianxi1 */ @WebServlet("/lianxi1") public class lianxi1 extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public lianxi1() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.getWriter().append("Served at: ").append(request.getContextPath()); // ServletContext servletContext = this.getServletContext(); if(servletContext.getAttribute("num")==null) { servletContext.setAttribute("num", 1); }else { int i =(int) servletContext.getAttribute("num")+1; servletContext.setAttribute("num",i); } //response.getWriter().println(" "+servletContext.getAttribute("host")); //response.getWriter().println("web vistied num:"+ servletContext.getAttribute("num")); request.setAttribute("count",servletContext.getAttribute("num")); //连接jsp(实现Servlet的请求转发) servletContext.getRequestDispatcher("/File1.jsp").forward(request, response); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
    <%@ 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>
    </head>
    <body>
               <!--jsp相当于一个 Servle对象-->
        <h1>hello:<%=request.getAttribute("count") %>></h1>
        </body>
    </html>
    
    
    
     

    3)实现Servlet的请求转发

     

    之前我们学过的请求转发是通过request对象的:

     

    request.getRequestDispatcher("/url").forward(request, response);

    这里要说明的是,ServletContext也可以实现请求转发:

     

    this.getServletContext().getRequestDispatcher("/url").forward(request, response);

    这两个转发效果是一样的。但是servletcontext转发 连接地址不会改变,只是页面改变

    package cn.sxt;
    
    import java.io.IOException;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    /**
     * Servlet implementation class lianxi2
     */
    @WebServlet("/lianxi2")
    public class lianxi2 extends HttpServlet {
        private static final long serialVersionUID = 1L;
           
        /**
         * @see HttpServlet#HttpServlet()
         */
        public lianxi2() {
            super();
            // TODO Auto-generated constructor stub
        }
    
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            response.getWriter().append("Served at: ").append(request.getContextPath());
         
            request.setAttribute("name", "cxk");
            //request请求转发,重定向路径会改变,请求转发路径不会改变
            //request.getRequestDispatcher("/lianxi1").forward(request, response);
         request.getRequestDispatcher("File1.jsp").forward(request, response);
        
        }
    
        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    }

    (3)利用ServletContext对象读取资源文件(比如properties文件):

    文件在WebRoot文件夹下,即我们的Web应用的根目录下。这时候我们可以使用ServletContext来读取该资源文件。

    假设我们Web根目录下有一个配置数据库信息的dbinfo.properties文件,里面配置了name和password属性,这时候可以通过ServletContext去读取这个文件:

    // 这种方法的默认读取路径就是Web应用的根目录

    InputStream stream = this.getServletContext().getResourceAsStream("dbinfo.properties");

    // 创建属性对象

    Properties properties = new Properties();

    properties.load(stream);

    String name = properties.getProperty("name");

    String password = properties.getProperty("password");

    out.println("name="+name+";password="+password);

    因为存在ServletContext中的数据会长时间保存在服务器,会占用内存,因此我们建议不要向ServletContext中添加过大的数据!

     

    package cn.sxt;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Properties;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    
    
    /**
     * Servlet implementation class lianxi2
     */
    @WebServlet("/lianxi2")
    public class lianxi2 extends HttpServlet {
        private static final long serialVersionUID = 1L;
           
        /**
         * @see HttpServlet#HttpServlet()
         */
        public lianxi2() {
            super();
            // TODO Auto-generated constructor stub
        }
    
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            response.getWriter().append("Served at: ").append(request.getContextPath());
         
            //设置properties文件路径
            InputStream resourceAsStream = this.getServletContext().getResourceAsStream("dbinfo.properties");
            Properties properties = new Properties();
            properties.load(resourceAsStream);
            response.getWriter().println("/nwebname:"+properties.getProperty("webname"));
        }
    
        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    }
  • 相关阅读:
    Python-05知识-01Python优缺点
    Python-02进阶-06代码优化工具
    Python-02进阶-04多进程多线程
    Python-02进阶-03生成器
    Python-02进阶-02装饰器
    Python-01基础-13功能模块
    Python-01基础-12常用命令
    Python-01基础-11基础知识
    console.dir有很多浏览器,系统的兼容性问题,不要随便用!
    微信支付-签名错误
  • 原文地址:https://www.cnblogs.com/406070989senlin/p/11025177.html
Copyright © 2011-2022 走看看