Servlet四大域对象

Servlet域对象

全局域对象

  1. ServletContext全局域对象,生命周期是服务器停止后结束

  2. 创建方式

    //设置全局域数据
    ServletContext context = this.getServletContext();
    context.setAttribute("username","zhangsan");
    context.setAttribute("password","123456");
    //获取全局域数据
    ServletConfig config = this.getServletConfig();
    ServletContext context = config.getServletContext();
    String username = (String) context.getAttribute("username");
    System.out.println(username);
    //删除全局域对象
    removeAttribute("username")
    
  3. 特点是:全局域对象共享的数据会一直存在服务器中,直到服务器停止了,这个对象才会消失。而且数据会被所以的servlet共享。

    例如

    package org.westos.demo;/*Author:LH
    CreatTime:2020.08.21.13:54*/
    
    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 java.io.IOException;
    
    @WebServlet(name = "org.westos.demo.Servlet1",value = "/demo1")
    public class Servlet1 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doGet(request, response);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            ServletContext context = request.getServletContext();
            context.setAttribute("username","zhangsan");
            context.setAttribute("password","123456");
        }
    }
    
    package org.westos.demo;/*Author:LH
    CreatTime:2020.08.21.13:56*/
    
    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 java.io.IOException;
    
    @WebServlet(name = "Servlet2",value = "/demo2")
    public class Servlet2 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doGet(request, response);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            ServletContext context = request.getServletContext();
            System.out.println(context.getAttribute("username"));
            System.out.println(context.getAttribute("password"));
        }
    }
    
    
    第一次请求demo1之后
    关闭浏览器,再请求demo2,不管是用哪个浏览器都可以请求到数据
    
  4. 注意点:由于全局域的范围很大,能被任何一个servlet访问到,所以在使用的时候要根据具体情况确定域的范围,不能滥用这个域对象,否则会造成资源的浪费。

请求域对象

  1. 请求域对象的范围只是一次请求,如果是重定向或者是多次请求,这个域对象的数据就不能被共享。

  2. 案例

   ```java
   package org.westos.demo2;/*Author:LH
   CreatTime:2020.08.21.14:11*/
   
   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 java.io.IOException;
   
   @WebServlet(name = "MyServlet",value = "/demo21")
   public class MyServlet extends HttpServlet {
       protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
           this.doGet(request, response);
       }
   
       protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
           request.setAttribute("username", "zhangsan");
           request.setAttribute("password", "123456");
       }
   }
   
   
   package org.westos.demo2;/*Author:LH
   CreatTime:2020.08.21.14:11*/
   
   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 java.io.IOException;
   
   @WebServlet(name = "Servlet1",value ="/demo22" )
   public class Servlet1 extends HttpServlet {
       protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
           this.doGet(request, response);
       }
   
       protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
           System.out.println(request.getAttribute("username"));
           System.out.println(request.getAttribute("password"));
       }
   }
   
   
   这样就属于两次请求了,所以第二次请求就拿不到数据,会获得null.
  1. 请求转发使用请求对象
   ```Java
   package org.westos.demo2;/*Author:LH
   CreatTime:2020.08.21.14:11*/
   
   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 java.io.IOException;
   
   @WebServlet(name = "MyServlet",value = "/demo21")
   public class MyServlet extends HttpServlet {
       protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
           this.doGet(request, response);
       }
   
       protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
           System.out.println("demo21请求来了");
           request.setAttribute("username", "zhangsan");
           request.setAttribute("password", "123456");
           request.getRequestDispatcher("/demo22").forward(request,response);
       }
   }
   
   package org.westos.demo2;/*Author:LH
   CreatTime:2020.08.21.14:11*/
   
   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 java.io.IOException;
   
   @WebServlet(name = "Servlet1",value ="/demo22" )
   public class Servlet1 extends HttpServlet {
       protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
           this.doGet(request, response);
       }
   
       protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
           System.out.println("demo22请求来了");
           System.out.println(request.getAttribute("username"));
           System.out.println(request.getAttribute("password"));
       }
   }
   
   
   结果:
   demo21请求来了
   demo22请求来了
   zhangsan
   123456
  1. 注意点:请求域对象的生存周期比较短,只是限于一次请求中或者请求转发。所以我们在使用时要注意,不然就共享不到数据。例如两次请求和重定向就请求不到数据。

会话技术

  1. 首先会话的生命周期是浏览器和服务器建立一次连接,这个连接中可以有多次请求多次响应,如果服务器断开,这次会话就结束了。

  2. http是无状态协议技术,通过cookie和session来提供历史记录。

  3. 客户端会话技术Cookie

    1. 数据存在客户端的技术,可以存储多个数据

    2. 原理:

      • 1.客户端请求一个资源,服务器做出响应时,会发送set-cookie头,共享数据
      • 2.客户端接收到响应,会将数据保存在客户端浏览器中
      • 3.客户端再一次请求服务器时,会通过cookie头携带该数据。
      • 4.服务端接收到请求,会来解析获取数据
    3. 案例演示

      package org.westos.demo3;/*Author:LH
      CreatTime:2020.08.21.15:12*/
      
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.Cookie;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      
      @WebServlet(name = "Servlet31" ,value = "/demo31")
      public class Servlet31 extends HttpServlet {
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              this.doGet(request, response);
          }
      
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              Cookie cookie = new Cookie("username", "zhangsan");
              response.addCookie(cookie);
          }
      }
      
      package org.westos.demo3;/*Author:LH
      CreatTime:2020.08.21.15:12*/
      
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.Cookie;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      
      @WebServlet(name = "Servlet32",value = "/demo32")
      public class Servlet32 extends HttpServlet {
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              this.doGet(request, response);
          }
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              System.out.println("demo32请求来了");
              Cookie[] cookies = request.getCookies();
              for (Cookie cookie : cookies) {
                  String name = cookie.getName();
                  if (name.equals("username")){
                      System.out.println(cookie.getValue());
                      System.out.println(cookie.getMaxAge());
                  }
              }
          }
      }
      
    4. 记住密码案例演示

      前端代码
      <%--
        Created by IntelliJ IDEA.
        User: ShenMouMou
        Date: 2020/8/18
        Time: 9:04
        To change this template use File | Settings | File Templates.
      --%>
      <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="utf-8" %>
      
        
          $Title$
        
        
        <%
            String uname="";
            String upwd="";
            Cookie[] cookies = request.getCookies();
            for (Cookie cookie2 : cookies) {
                String name = cookie2.getName();
                if (name.equals("username")){
                    uname= cookie2.getValue();
      
                }
                if (name.equals("password")) {
                    upwd = cookie2.getValue();
                }
            }
        %>
            

      用户登录

      用户名:
      密 码:
      //后端
      package org.westos.demo;/*Author:LH
      CreatTime:2020.08.20.11:43*/
      
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.Cookie;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      
      @WebServlet(name = "MyServlet1",value = "/demo1")
      public class MyServlet1 extends HttpServlet {
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              this.doGet(request, response);
          }
      
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              String username = request.getParameter("username");
              String password = request.getParameter("password");
              Cookie cookie = new Cookie("username", username);
              Cookie cookie1 = new Cookie("password", password);
              response.addCookie(cookie);
              response.addCookie(cookie1);
          }
      }
      
    5. 注意点:

      • 不跨浏览器记录。换了浏览器第二次就不会读取到

      • 默认存在浏览器的内存中。浏览器关闭之后,再次请求就没cookie了。

        • 为了解决这个问题,我们可以设置cookie的存活周期,cookie可以存在客户端的硬盘上。指定保存时间。时间到了自动清除,或者自己提前手动清除
      • 在服务器之前的版本中不支持存储中文,现在8.5以上的可以存中文。不支持:发送前编码,结束后解码。

        • 如果服务器不支持中文的时候

          • 方案:将Cookie数据转化为非中文数据存储使用URL编码 解码
            Cookie uc = new Cookie(“username”, URLEncoder.encode(username, “utf-8”));//编码
            Cookie pc = new Cookie(“password”, URLEncoder.encode(password, “utf-8”));//编码

            username = URLDecoder.decode(c.getValue(), “utf-8”);//解码
            password = URLDecoder.decode(c.getValue(), “utf-8”);//解码

  4. 服务端会话技术(Session)

    1. 是将数据存在服务端,session依赖cookie存在。

    2. package org.westos.demo4;/*Author:LH
      CreatTime:2020.08.21.16:10*/
      
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.*;
      import java.io.IOException;
      
      @WebServlet(name = "Servlet41",value = "/demo41")
      public class Servlet41 extends HttpServlet {
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              this.doGet(request, response);
          }
      
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              System.out.println("demo41请求来了");
              HttpSession session = request.getSession();
              session.setAttribute("username","zhangsan");
              request.getRequestDispatcher("/demo42").forward(request,response);
          }
      }
      
      
      package org.westos.demo4;/*Author:LH
      CreatTime:2020.08.21.16:10*/
      
      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;
      import java.io.IOException;
      
      @WebServlet(name = "Servlet42",value = "/demo42")
      public class Servlet42 extends HttpServlet {
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              this.doGet(request, response);
          }
      
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              System.out.println("demo42请求来了");
              HttpSession session = request.getSession();
              String username = (String) session.getAttribute("username");
              System.out.println(username);
          }
      }
      /*结果
      demo41请求来了
      A989E1A8546EC14D642D993E8F65F986
      demo42请求来了
      A989E1A8546EC14D642D993E8F65F986
      zhangsan
      */
      
    3. 细节;

      • 浏览器关闭,cookie会话结束,session会话也结束,数据就不存在了。
      • 浏览器不关闭,服务器关闭,session数据会被保存在硬盘上(钝化),服务器启动数据从硬盘上被读取(活化)称之为钝化和活化机制
        • 浏览器关闭了,session不一样了。Cookie没了。jsessionid没了。
        • 服务器关闭了,session一样吗?不一样。内存释放了。优化:虽然对象不一样了,但是session中存储的数据还是一样的。

      图示服务器停止后的存储位置,服务器启动就是文件所在地址。

      Servlet四大域对象_第1张图片

      Servlet四大域对象_第2张图片

      • 生命周期:

        • 通过getSession()创建

        • 销毁:服务器关闭。

          ​ 会话超时:我们可以设置会话时间,在配置文件里面设置

          ​ < session-config>
          ​ < session-timeout>30< /session-timeout>
          ​ < /session-config>

          ​ 手动销毁:session对象调用 invalidate() 方法,自己销毁

      • 如果getSession()时没有获取到原来的对象,服务器会自动创建一个新的对象,只是这个对象的值为null。

      • 如果客户端的cookie被禁止了怎么办

        因为客户进入每个页面点击任何一个东西都是超链接,所以在连接的后面拼上sessionID,通过连接将id传过去,服务器就可以读取到数据。

        案例

        package org.westos.demo;
        
        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;
        import java.io.IOException;
        
        @WebServlet(name = "IndexServlet", value = "/index")
        public class IndexServlet extends HttpServlet {
            protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                HttpSession session = request.getSession();
                session.setAttribute("name", "呵呵");
              /*  String id = session.getId();
         session.setAttribute("name", "呵呵");
        
                response.getWriter().write("demo2");
        */
                String url = "/20200820___war_exploded/demo2";
                //encodeRedirectURL(url); URL重写,会把jsessionid 给你拼好
                url = response.encodeRedirectURL(url);
                System.out.println(url);
                response.getWriter().write("demo2");
            }
        
            protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                this.doPost(request, response);
            }
        }
        
        package org.westos.demo;
        
        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;
        import java.io.IOException;
        
        @WebServlet(name = "ServletDemo2", value = "/demo2")
        public class ServletDemo2 extends HttpServlet {
            protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                System.out.println("/demo2收到请求了");
                HttpSession session = request.getSession();
                System.out.println(session.getId());
                System.out.println(session.getAttribute("name"));
            }
            protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                this.doPost(request, response);
            }
        }
        
        //结果
        /20200820___war_exploded/demo2
        /demo2收到请求了
        D5F9E2F628E2839420A00ECCC1D94EAB
        呵呵
        
        

域对象的选取

根据数据的使用次数选择

使用次数 对象 条件
一次请求 请求域对象 一次请求/请求转发
一次连接多次请求 会话域 可以是重定向
所有对象都使用 全局域对象
            |

还有一个域对象等待分析。。。。。。。。

你可能感兴趣的:(Java,web,servlet)