Servlet3-Cookie、Session、ServletContext、ServletConfig

会话跟踪技术

会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应。
会话跟踪:一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据。
HTTP协议是无状态的,每次浏览器向服务器请求时,服务器都会将该请求视为新的请求,因此我们需要会话跟踪技术来实现会话内数据共享。
实现方式:
Cookie技术:会话数据保存在浏览器客户端。
Session技术:会话数据保存在服务器端。(域对象)

Cookie技术

客户端会话技术,将数据保存到客户端,以后每次请求都携带Cookie数据进行访问

Cookie 基本使用

发送Cookie
  创建Cookie对象,设置数据
    Cookie cookie = new Cookie("key","value");
  发送Cookie到客户端:使用response对象
    response.addCookie(cookie);

 1 @WebServlet("/aServlet")
 2 public class AServlet extends HttpServlet {
 3     @Override
 4     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 5         //发送Cookie
 6         //1. 创建Cookie对象
 7         Cookie cookie = new Cookie("username","zs");
 8         //2. 发送Cookie,response
 9         response.addCookie(cookie);
10     }
11     @Override
12     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
13         this.doGet(request, response);
14     }
15 }

获取Cookie
  获取客户端携带的所有Cookie,使用request对象
    Cookie[] cookies = request.getCookies();
  遍历数组,获取每一个Cookie对象:for
  使用Cookie对象方法获取数据
    cookie.getName();
    cookie.getValue();

 1 @WebServlet("/bServlet")
 2 public class BServlet extends HttpServlet {
 3     @Override
 4     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 5         //获取Cookie
 6         //1. 获取Cookie数组
 7         Cookie[] cookies = request.getCookies();
 8         //2. 遍历数组
 9         for (Cookie cookie : cookies) {
10             //3. 获取数据
11             String name = cookie.getName();
12             if("username".equals(name)){
13                 String value = cookie.getValue();
14                 System.out.println(name+":"+value);
15                 break;
16             }
17         }
18     }
19     @Override
20     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
21         this.doGet(request, response);
22     }
23 }

Cookie 原理

Cookie的实现是基于HTTP协议的
响应头:set-cookie
请求头:cookie

Cookie 使用细节

Cookie 存活时间

默认情况下,Cookie 存储在浏览器内存中,当浏览器关闭,内存释放,则Cookie被销毁。
setMaxAge(int seconds):设置Cookie存活时间(seconds单位为秒)
  正数:将 Cookie写入浏览器所在电脑的硬盘,持久化存储。到时间自动删除
  负数:默认值,Cookie在当前浏览器内存中,当浏览器关闭,则 Cookie被销毁
  零:删除对应 Cookie

 1 @WebServlet("/aServlet")
 2 public class AServlet extends HttpServlet {
 3     @Override
 4     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 5         //发送Cookie
 6         //1. 创建Cookie对象
 7         Cookie cookie = new Cookie("username","zs");
 8         //设置存活时间,1周 7天
 9         cookie.setMaxAge(60*60*24*7); //易阅读,需程序计算
10         //cookie.setMaxAge(604800); //不易阅读(可以使用注解弥补),程序少进行一次计算
11         //2. 发送Cookie,response
12         response.addCookie(cookie);
13     }
14     @Override
15     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
16         this.doGet(request, response);
17     }
18 }

Cookie 存储中文

Cookie 不能直接存储中文
如需要存储,则需要进行转码:URL编码
对中文进行URL编码:

 1 @WebServlet("/aServlet")
 2 public class AServlet extends HttpServlet {
 3     @Override
 4     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 5         //发送Cookie
 6         String value = "张三";
 7         //对中文进行URL编码
 8         value = URLEncoder.encode(value, "UTF-8");
 9         System.out.println("存储数据:"+value);
10         //将编码后的值存入Cookie中
11         Cookie cookie = new Cookie("username",value);
12         //设置存活时间   ,1周 7天
13         cookie.setMaxAge(60*60*24*7);
14         //2. 发送Cookie,response
15         response.addCookie(cookie);
16     }
17     @Override
18     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
19         this.doGet(request, response);
20     }
21 }

对值进行解码:

 1 @WebServlet("/bServlet")
 2 public class BServlet extends HttpServlet {
 3     @Override
 4     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 5         //获取Cookie
 6         //1. 获取Cookie数组
 7         Cookie[] cookies = request.getCookies();
 8         //2. 遍历数组
 9         for (Cookie cookie : cookies) {
10             //3. 获取数据
11             String name = cookie.getName();
12             if("username".equals(name)){
13                 String value = cookie.getValue();//获取的是URL编码后的值 %E5%BC%A0%E4%B8%89
14                 //URL解码
15                 value = URLDecoder.decode(value,"UTF-8");
16                 System.out.println(name+":"+value);//value解码后为 张三
17                 break;
18             }
19         }
20     }
21     @Override
22     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
23         this.doGet(request, response);
24     }
25 }

注意:
  一个Cookie对象存储一条数据。多条数据,可以多创建几个Cookie对象进行存储。

特点

  浏览器端的数据存储技术。
  存储的数据声明在服务器端。
  临时存储:存储在浏览器的运行内存中,浏览器关闭即失效。
  定时存储:设置了Cookie的有效期,存储在客户端的硬盘中,在有效期内符合路径要求的请求都会附带该信息。
  默认cookie信息存储好之后,每次请求都会附带,除非设置有效路径

Session技术

服务端会话跟踪技术:将数据保存到服务端。
  Session是存储在服务端而Cookie是存储在客户端。
  存储在客户端的数据容易被窃取和截获,存在很多不安全的因素。
  存储在服务端的数据相比于客户端来说就更安全。

Session 基本使用

JavaEE 提供 HttpSession接口,来实现一次会话的多次请求间数据共享功能。
获取Session对象:
  HttpSession session = request.getSession();
Session对象功能:
  void setAttribute(String name, Object o):存储数据到 session 域中
  Object getAttribute(String name):根据 key,获取值
  void removeAttribute(String name):根据 key,删除该键值对

SessionDemo1:获取Session对象、存储数据

 1 @WebServlet("/demo1")
 2 public class SessionDemo1 extends HttpServlet {
 3     @Override
 4     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 5         //存储到Session中
 6         //1. 获取Session对象
 7         HttpSession session = request.getSession();
 8         //2. 存储数据
 9         session.setAttribute("username","zs");
10     }
11     @Override
12     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
13         this.doGet(request, response);
14     }
15 }

SessionDemo2:获取Session对象、获取数据

 1 @WebServlet("/demo2")
 2 public class SessionDemo2 extends HttpServlet {
 3     @Override
 4     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 5         //获取数据,从session中
 6         //1. 获取Session对象
 7         HttpSession session = request.getSession();
 8         //2. 获取数据
 9         Object username = session.getAttribute("username");
10         System.out.println(username);
11     }
12     @Override
13     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
14         this.doGet(request, response);
15     }
16 }

Session 原理

Session是基于Cookie实现的

  用户第一次访问服务器,服务器会创建一个session对象给此用户,并将该session对象的JSESSIONID使用Cookie技术存储到浏览器中,保证用户的其他请求能够获取到同一个session对象,也保证了不同请求能够获取到共享的数据。

Session 使用细节

Session 钝化、活化

服务器是正常关闭和启动,Session中的数据是可以被保存下来的,原因为:
钝化:在服务器正常关闭后,Tomcat会自动将 Session数据写入硬盘的文件中。
  钝化的数据路径为:项目目录\target\tomcat\work\Tomcat\localhost\项目名称\SESSIONS.ser。
活化:再次启动服务器后,从文件中加载数据到Session中。
  数据加载到Session中后,路径中的 'SESSIONS.ser' 文件会被删除掉。
注:
  session数据存储在服务端,服务器重启后,session数据会被保存。
  浏览器被关闭启动后,重新建立的连接就已经是一个全新的会话,获取的session数据也是一个新的对象。
  session的数据要想共享,浏览器不能关闭,所以session数据不能长期保存数据。
  cookie是存储在客户端,是可以长期保存。

Seesion 销毁

1、默认情况下,无操作,30分钟自动销毁。
  对于这个失效时间,是可以通过配置进行修改的:在项目的web.xml中配置

<session-config>
    <session-timeout>100</session-timeout>
</session-config>

2、调用Session对象的invalidate()方法进行销毁。

session.invalidate();

  该销毁方法一般会在用户退出的时候,需要将session销毁掉。

特点

  存储在服务器端
  服务器进行创建
  依赖Cookie技术
  一次会话
  默认存储时间是30分钟

小结

Cookie 和 Session 都是来完成一次会话内多次请求间数据共享的。
区别:
  存储位置:Cookie 是将数据存储在客户端,Session 将数据存储在服务端。
  安全性:Cookie 不安全,Session 安全。
  数据大小:Cookie 最大3KB,Session 无大小限制。
  存储时间:Cookie 可以长期存储,Session 默认30分钟。
  服务器性能:Cookie 不占服务器资源,Session 占用服务器资源。

ServletContext对象(Servlet上下文对象)

问题:
  不同的用户使用相同的数据
解决:
  ServletContext对象
特点:
  服务器创建
  用户共享
  一个项目只有一个
作用域:
  整个项目内
生命周期:
  服务器启动到服务器关闭

ServletContext配置方式

在<web-app>标签中,通过<context-param>标签来配置。有两个子标签。
<param-name>:代表全局初始化参数的 key。
<param-value>:代表全局初始化参数的value。

<!--配置ServletContext-->
<context-param>
    <param-name>globalEncoding</param-name>
    <param-value>UTF-8</param-value>
</context-param>
<context-param>
    <param-name>globalDesc</param-name>
    <param-value>This is ServletContext</param-value>
</context-param>

ServletContext使用

1、获取ServletContext对象
//第一种方式:
  ServletContext sc=this.getServletContext();
//第二种方式:
  ServletContext sc2=this.getServletConfig().getServletContext();
//第三种方式:
  ServletContext sc3=req.getSession().getServletContext();

2、使用ServletContext对象完成数据共享
//向应用域对象中存储数据
  sc.setAttribute(String name, Object value);
//通过名称获取应用域对象中的数据
  sc.getAttribute("str") 返回的是Object类型
//通过名称移除应用域对象中的数据
  sc.removeAttribute("str")
注意:
不同的用户可以给ServletContext对象进行数据的存取。
获取的数据不存在返回null。

3、获取项目中web.xml文件中的全局配置数据
sc.getInitParameter(String name); 根据键的名字返回web.xml中配置的全局数据的值,返回String类型。
  如果数据不存在返回null。
sc.getInitParameterNames();返回键名的枚举
  配置方式:注意一组<context-param>标签只能存储一组键值对数据,多组可以声明多个 <context-param>进行存储。
    在<servlet>上,在<web-app>下:
      <context-param>
        <param-name>name</param-name>
        <param-value>zhangsan</param-value>
      </context-param>
  作用:将静态数据和代码进行解耦。
4、获取web应用的上下文路径
String path=sc.getContextPath();
  获取web应用上下路径。也就是部署到tomcat服务器上运行的web应用名称。
    例:重定向:resp.sendRedirect("/login/main");  写成:resp.sendRedirect(sc.getContextPath()+"/main");
5、获取项目webroot下的资源的绝对路径。
String path=sc.getRealPath(String path); 
  获取的路径为项目根目录,path参数为项目根目录中的路径
6、获取webroot下的资源的流对象
InputStream is = sc.getResourceAsStream(String path);
  注意:
    此种方式只能获取项目根目录下的资源流对象,class文件的流对象需要使用类加载器获取。
    path参数为项目根目录中的路径
7、获取webroot下的资源的URL
URL url = sc.getResource(String path);
  能获取一个URL,不能构造输入流。

 1 protected void service(HttpServletRequest req, HttpServletResponse resp)
 2         throws ServletException, IOException {
 3     //获取ServletContext对象
 4         //第一种方式:
 5         ServletContext sc=this.getServletContext();
 6         //第二种方式:
 7         ServletContext sc2=this.getServletConfig().getServletContext();
 8         //第三种方式:
 9         ServletContext sc3=req.getSession().getServletContext();
10         System.out.println(sc==sc2);
11         System.out.println(sc==sc3);
12     //使用ServletContext对象完成数据共享
13         //数据存储
14         sc.setAttribute("str", "ServletContext对象学习");
15     //获取项目web.xml的全局配置数据
16         String str = sc.getInitParameter("name2");
17         System.out.println("全局配置参数:"+str);
18     //获取项目根目录下的资源的绝对路径
19         //String path="D:\\apache-tomcat-7.0.56\\webapps\\sc\\doc\\1.txt";
20         String path=sc.getRealPath("/doc/1.txt");
21         System.out.println(path);
22     //获取项目根目录下资源的流对象
23         InputStream is = sc.getResourceAsStream("/doc/1.txt");
24 
25 }
1 protected void service(HttpServletRequest req, HttpServletResponse resp)
2         throws ServletException, IOException {
3     //创建ServletContext对象
4         ServletContext sc=this.getServletContext();
5     //获取数据
6         System.out.println("ServletContextServlet2.service()"+sc.getAttribute("str"));
7 }

ServletConfig对象

问题:
  如何获取在web.xml中给每个servlet单独配置的数据呢?
解决:
  使用ServletConfig对象
注意:ServletConfig对象是在创建完servlet对象之后,被创建出来。然后通过有参数的init方法传递到servlet中。 一个网站中存在多个ServletConfig对象,一个ServletConfig对象就封存了一个Servlet的配置信息。
使用:
  获取ServletConfig对象
  获取web.xml中的配置数据
    在<servlet>中添加:
    <init-param>
      <param-name>config</param-name>
      <param-value>utf-8</param-value>
    </init-param>

1 protected void service(HttpServletRequest req, HttpServletResponse resp)
2         throws ServletException, IOException {
3     //获取ServletConfig对象
4     ServletConfig sc=this.getServletConfig();
5     //获取web.xml中的配置数据
6     String code=sc.getInitParameter("config");
7     System.out.println(code);
8 }

ServletConfig常用方法

String getlnitParameter(String name)   根据参数名称获取参数的值
Enumeration<String> getlnitParameterNames()   获取所有参数名称的枚举
String getServletName()   获取Servlet的名称
ServletContext getServletContext()   获取ServletContext对象

web.xml文件使用

作用:
  存储项目相关的配置信息,保护 Servlet。解耦一些数据对程序的依赖。
使用位置:
  每个 Web 项目中
  Tomcat 服务器中(在服务器目录 conf 目录中)
区别:
  Web 项目下的 web.xml 文件为局部配置,针对本项目的位置。
  Tomcat 下的 web.xml 文件为全局配置,配置公共信息。
内容(核心组件):
  全局上下文配置(全局配置参数)
  Servlet 配置
  过滤器配置
  监听器配置
加载顺序:
  Web 容器会按 ServletContext -> context-param -> listener ->filter-> servlet 这个顺序加载组件,这些元素可配置在 web.xml文件中的任意位置。
加载时机:
  服务器启动时。

server.xml文件使用

Server.xml 文件核心组件:

<Server> 
    <Service> 
        <Connector/> 
        <Connector/> 
        <Engine> 
            <Host> 
                <Context/> 
            </Host> 
        </Engine> 
    </Service>
</Server>

热部署: <Context path="/Pet" reloadable="true" docBase="F:/PetWeb" />
  path: 项目访问路径
  docBase: 项目路径。/开头的是实际路径,没有/开头的为相对路径,相对于webapps
  reloadable: 开启热更新,热部署

 

posted @ 2020-03-17 23:50  溯鸣  阅读(200)  评论(0编辑  收藏  举报