目录标题
什么是 Cookie?
Cookie 的中文意思是 饼干、小甜点。我们可以把它理解成是由 服务器发给客户端一个小礼物。
Cookie是一种浏览器和服务器交互数据的方式;
Cookie是由服务器端创建,但是不会保存在服务器;
创建好之后,发送给浏览器。浏览器保存在用户本地;
下一次访问网站的时候,就会把该Cookie发送给服务器。
当客户端第一次请求来到服务端时,服务端会通过响应头把一小段信息写给客户端,客户端以cookie
的方式来存储这段信息。 这一段信息涉及到如下头信息:
cookie: xxxxx
set-cookie: xxxx
当然,客户端可以自由选择是否要接受服务端的“馈赠",也就是说客户端可以决定是否启用cookie.
默认情况下,浏览器的cookie是打开的。
由于HTTP协议是无状态的,所以服务端通过浏览器提供的cookie机制做为一种记录客户端的手段。
只要客户端浏览器接受了服务端的“馈赠",那服务端就可以“识别”这个客户端。
如何操作 Cookie?
首先要明白 cookie是服务端发送给客户端的一小段信息。
其次,我们可以通过 HttpServletResponse.addCookie(Cookie c) 方法把具体的信息发送给客户端。
最后,我们也可以通过 HttpServletRequest.getCookies() 方法来获取客户端发回来的cookie数据。
Cookie 头信息和流程 如下图所示:
本案例演示 Cookie 的添加和获取
- servlet03\servlet\CookieServlet.javal 代码如下:
package com.guyu.servlet03.servlet;
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;
import java.io.PrintWriter;
/**
* 本案例演示 cookie的添加和获取
*/
@WebServlet(urlPatterns = "/cookie")
public class CookieServlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter pw = resp.getWriter();
//0. 先判断是否有cookie
Cookie[] cookies = req.getCookies();
if(cookies != null && cookies.length > 0) {
//说明已经存在 cookie, 迭代
for(Cookie c : cookies) {
pw.println("<h2 align=\"center\">以下是cookie的值</h2>");
pw.println("<div style='border:1px solid red;margin-left:750px;margin-right:750px'>");
pw.println(" <p align=\"center\">Cookie名: "+c.getName()+"</p>");
pw.println(" <p align=\"center\">Cookie值: "+c.getValue()+"</p>");
pw.println(" <p align=\"center\">Cookie Domain: "+c.getDomain()+"</p>");
pw.println(" <p align=\"center\">Cookie Path: "+c.getPath()+"</p>");
pw.println(" <p align=\"center\">Cookie Max-Age: "+c.getMaxAge()+"</p>");
pw.println("</div>");
}
} else {
//说明没有cookie 需要清除浏览数据 ctrl+shift+delete
//1.负责向客户端写 cookie
//创建两个Cookie
Cookie c1 = new Cookie("_user","guyu");
//c1.setDomain("127.0.0.1");
//c1.setPath("/cookie");
//设置 Cookie 有效期其时长为 一分钟
//当第一次访问 http://127.0.0.1:10086/hs/cookie 时,等待60s后再点击查看 cookie 时
//此时 cookie 过期,request 会请求不到,反之60s内请求可查看其 cookie
c1.setMaxAge(60);
Cookie c2 = new Cookie("_pwd", "root");
//psd 密码有效期时长 30s
c2.setMaxAge(30);
//2.把这两个cookie写到客户端,添加到响应
resp.addCookie(c1);
resp.addCookie(c2);
//3.输出一个超链接,让用户查看cookie
pw.println("<h2 align=\"center\"><a href='"+
req.getContextPath()+"/cookie'>查看cookie</a></h2>");
}
//关闭
pw.close();
}
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
}
- 运行后在浏览器输入 http://127.0.0.1:10086/hs/cookie 时,响应头内会显示设置其 cookie 的所有数据如下图所示:
- 在其 30s 内点击查看 cookie 时 ,请求头内会显示其 cookie 的所有数据:
- 重运行后若在其 30s 后点击查看 cookie 时 ,请求头内只会显示其 第一个 cookie 的数据值,因为第二个 cookie 的数据值有效期为 30s:
重运行后反之若在其 60s 后点击查看 cookie 时 ,此时数据值都已失效。
注:
request【请求】是获取用户的请求,response【响应】 是处理用户请求。
当客户端第一次请求来到服务端时,服务端会通过响应头把一小段信息写给客户端,
客户端以cookie的方式来存储这段信息。
什么是 Session?
Session 指会话,它是服务器用来标识浏览器的一种手段。【因为HTTP协议是无状态的】
它是指从用户打开浏览器访问一个网站开始,无论在这个网站中访问了多少页面,点击
了多少链接,都属于同一个会话; 直到该用户关闭浏览器为止,都属于同一个会话。
Session 的实现原理:
①. 基于cookie的实现
当客户端的请求来到服务器时,服务端会自动生成一个唯一性的字符串,名为 JSESSIONID,并维护 这个会话列表。【注:需要在服务端中调用 req.getSession() 方法来启动会话管理,默认会话是 不开启的】 当服务端生成这个 JSESSIONID 后,以 jsessionID 为 name,配合它的值生成一个 cookie对象,并 且自动随响应发送给客户端。 客户端接受这个cookie,以后每次请求都会自动带上这个cookie,发回给服务端。
②. 基于URL重写机制的实现 【当浏览器禁用 cookie 时】
原始URL: http://localhost:10086/hs/protected/main 经过URL重写机制后,变成: http://localhost:10086/hs/protected/main?jsessionid=CC733EE326116917E135668A594C02ED 如: String url = "/protected/main"; String e_url = resp.encodeURL(url); //如果客户端禁用了 cookie, 则上面的方法的返回值是: /protected/main;jsessionid=CC733EE326116917E135668A594C02ED
Session 两种实现方式 如下图所示:
默认情况下,session 的过期时间是 30分钟。
当客户端与服务端超过 30 分钟没有交互,则客户端的 JSESSIONID 会自动过期,服务端同样会过期。
修改 Session 的过期时间
在 web.xml 中,做如下配置:
<!-- 配置 Session 会话的超时时间 -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
本案例演示 Session 会话管理
- servlet04\servlet\SessionServlet.java 代码如下:
package com.guyu.servlet04.servlet;
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;
import java.util.Date;
/**
* @Author: Fred
* @Date: 2020/10/22 14:25
*
* Session 会话管理的演示
*/
@WebServlet(urlPatterns = "/session")
public class SessionServlet extends HttpServlet {
@Override
public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession(true);
//这种情况,Session是一定能获取的,所以无需做非空判断
System.out.println("服务端创建了session,它的ID是:"+session.getId());
//输出创建时间
System.out.printf("session创建时间:"+new Date(session.getCreationTime()));
//输出间隔时间
System.out.printf("间隔时间:"+session.getMaxInactiveInterval());
}
}
注:进入浏览器请求前 需要清浏览缓存数据。 (快捷键:ctrl+shift+delete)
- 运行后在浏览器输入 http://127.0.0.1:10086/hs/session 时,响应头内会显示其 sessionId 的数据值,如下图所示:
- 在控制台中输出的数据 如下图所示:
Cookie 和 Session 两者区别:
什么是 Filter?
Filter 被称作 过滤器或拦截器,其基本功能就是对 Servlet 容器调用 Servlet 的过程进行拦截,从而在 Servlet 进行响应处理前后实现一些特殊功能。这就好比现实中的污水净化设备,它可以看作一个过滤器,专门用于过滤污水杂质。
它也是由 web container 进行管理的,与 Servlet 类似,它也有自己的生命周期,分别是如下三个方法:
void init(FilterConfig config)
void doFilter(request, response, FilterChain chain)
void destroy()
再来看看 FilterChain [过滤链]
void doFilter(request, response, FilterChain chain)
再来看看 FilterConfig
String getInitParameter(name); 获取Filter 初始化参数
如何开发一个 Filter?
写一个类,实现 Filter 接口即可。
有关 Filter 的配置
urlPatterns: 就是指此过滤器能够匹配的请求URL被匹配上的请求url,就会进入此 Filter的 doFilter方法
servletNames: 是指此过滤器要保护的多个或一个Servlet。
initParams: 配置过滤器的初始化参数
dispatcherTypes: 指定哪种类型的请求会经过此过滤器,它的值是一个或多个枚举值,如:
ASYNC 异步处理的Servlet
ERROR
INCLUDE
FORWARD 转发
REQUEST 默认值
Filter 生命周期
1. 当容器启动,开载应用时,此应用中的所有Filter都会被 创建出来,并调用 init 方法。
2. 当请求来到时,被Filter 匹配上后,则执行 Filter的 doFilter方法,在此方法中,你可以根据
自己的业务要求,决定是否要放行这个请求。
如果调用了 filterChain.doFilter(servletRequest, servletResponse) 方法,则表示放行。
如果不调用,则应该把此请求转发或重定向到其它的资源。
3. 当容器去updeploy应用时,则会调用此应用中的所有 Filter 的 destroy方法。
web.xml 配置各节点说明
<filter> 指定一个过滤器。
<filter-name>用于为过滤器指定一个名字,该元素的内容不能为空。
<filter-class>元素用于指定过滤器的完整的限定类名。
<init-param>元素用于为过滤器指定初始化参数,它的子元素
<param-name>指定参数的名字,
<param-value>指定参数的值。
在过滤器中,可以使用FilterConfig接口对象来访问初始化参数。
<filter-mapping>元素用于设置一个 Filter 所负责拦截的资源。
一个Filter拦截的资源可通过两种方式来指定:Servlet 名称和资源访问的请求路径
<filter-name>子元素用于设置filter的注册名称。
该值必须是在<filter>元素中声明过的过滤器的名字
<url-pattern>设置 filter 所拦截的请求路径(过滤器关联的URL样式)
<servlet-name>指定过滤器所拦截的Servlet名称。
<dispatcher>指定过滤器所拦截的资源被 Servlet 容器调用的方式,
可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST。
用户可以设置多个<dispatcher>子元素用来指定 Filter 对资源的多种调用方式进行拦截。
<dispatcher>子元素可以设置的值及其意义:
REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。
INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。
什么是 Listener?
Listener 指监听器,监听 Web 服务器的运行,当发生特定的事件时,采取预先设定的处理措施的组件。
Servlet 的监听器,它可以监听客户端的请求、服务端的操作等。通过监听器,可以自动激发一些操作,比如监听在线的用户的数量。
它也是基于事件监听模型来建立的,包含 :
事件源 【预先定义好的】
事件监听者 【由程序员开发, 实现Listener 接口 】
事件对象 【是预先定义好的, 提供获取事件源的方法】
当事件发生时,容器会调用事件监听者的方法,以事件对象为参数。
它主要分为两大类:
一类是监听对象的生命周期的;
另一类是监听对象的绑定和解除的。
在Servlet的体系中,如下几个对象是最重要的:
HttpServletRequest / HttpServletResponse 请求对象
setAttribute(String key, Object value);
removeAttribute(String key);
HttpSession 会话对象
setAttribute(String key, Object value);
removeAttribute(String key);
ServletContext 应用上下文对象
setAttribute(String key, Object value);
removeAttribute(String key);
监听生命周期的类型:
ServletRequestListener 监听请求 生命周期的。
HttpSessionListener 监听HttpSession 生命周期的。
ServletContextListener 监听应用 生命周期 。
ServletContextListener
requestInitialized 在容器启动时被调用(在servlet被实例化前执行)
requestDestroyed 在容器销毁时调用(在servlet被销毁后执行)
HttpSessionListener
sessionCreated 在HttpSession创建后调用
sessionDestroyed 在HttpSession销毁前调用(执行session.invalidate();方法)
ServletRequestListener
requestDestroyed 在request对象创建后调用(发起请求)
requestInitialized 在request对象销毁前调用(请求结束)
事件源 事件对象 事件监听者
ServletRequest ServletRequestEvent 你的类实现ServletRequestListener接口
HttpSession HttpSessionEvent 实现 HttpSessionListener 接口
ServletContext ServletContextEvent 实现 ServletContextListener 接口
监听对象的绑定和解除的类型:
ServletRequestAttributeListener 监听请求范围的对象绑定和解除
HttpSesssionAttributeListener 监听会话范围的对象(所有对象)绑定和解除
HttpSessionBindingListener 监听会话范围的对象(限定指定的对象)绑定和解除
ServletContextAttributeListener 监听应用范围的对象 绑定和解除
事件源 事件对象 事件监听者
ServletRequest ServletRequestAttributeEvent ServletRequestAttributeListener
HttpSession HttpSessionBindingEvent HttpSesssionAttributeListener
HttpSession HttpSessionBindingEvent HttpSessionBindingListener
ServletContext ServletContextAttributeEvent ServletContextAttributeListener
通过 Listener 我们可以监听 Web 应用程序的生命周期,获取 HttpSession 等创建和销毁的事件;
ServletContext 是一个 WebApp 运行期的全局唯一实例,可用于设置和共享配置信息。
Note:
欢迎点赞,留言,转载请在文章页面明显位置给出原文链接
知者,感谢您在茫茫人海中阅读了我的文章
没有个性 哪来的签名!
详情请关注点我
持续更新中

© 2020 10 - Guyu.com | 【版权所有 侵权必究】 |