JavaWeb学习笔记:一文叙说Servlet、Session与Cookie、Servlet3.0注解、过滤器与监听器

文章目录

    • 1. Java Web
      • 1.1基本概念
      • 1.2 web的分类
      • 1.3 web应用程序
      • 1.4 web服务器
    • 2. Http协议简介
      • 2.1 基本概念
      • 2.2 网站的访问
        • 2.2.1 访问的简要过程
        • 2.2.2 http请求
          • 2.2.2.1 请求行(General,不属于headers,只用于收集请求url和响应的status等信息)
          • 2.2.2.2 请求头(Request Headers)
        • 2.2.3 Http响应
          • 2.2.3.1 响应头(Response Headers)
          • 2.2.3.2 响应状态码
    • 3. Servlet
      • 3.1 什么是Servlet?
      • 3.2 Servlet的工作模式
      • 3.3 开发Servlet的步骤
      • 3.4 服务器程序处理请求的大致过程
      • 3.5 Servlet工作原理
      • 3.6 Servlet的生命周期
      • 3.7 请求Request
        • 3.7.1 常用方法
        • 3.7.2 前端页面发送请求的方式
      • 3.8 响应Response
        • 3.8.1 常用方法
        • 3.8.2 请求转发与重定向区别
    • 4. 会话
      • 4.1 Session
        • 4.1.1 常用方法
        • 4.1.2 Session的生命周期
      • 4.2 Cookie
        • 4.2.1 Cookie的常见作用
        • 4.2.2 Cookie的设置、获取以及有效时间
      • 4.3 Session与Cookie的区别
    • 5. 设置与获取初始化参数
      • 5.1 局部初始化参数
      • 5.2 全局初始化参数
      • 5.3 会话失效时间
    • 6. Servlet3.0注解
    • 7. 过滤器Filter
      • 7.1 过滤器的概念
      • 7.2 过滤器的使用
      • 7.3 过滤器的生命周期
      • 7.4 过滤器使用场景
    • 8. 监听器Listener
      • 8.1 监听器的相关概念
      • 8.2 监听器的分类
      • 8.3 监听器的使用(以HttpSession域的监听器为例)
      • 8.4 监听器的生命周期与作用
    • 9. Servlet、过滤器Filter、监听器Listener加载的先后顺序

1. Java Web

1.1基本概念

​ web简单理解就是网页的意思,例如 www.baidu.com。在java中,动态web资源开发的技术统称为Java Web。



1.2 web的分类

  • 静态web

    提供给用户的数据始终不会发生改变,例如:

    • html、css、js
      • 优点:如果服务器上一直存在这些东西,我们可以直接进行读取;
      • 缺点
        1. web页面无法动态更新,所有用户都是看到同一页面(轮播图、伪动态、js……);
        2. 无法和数据库交互,使得数据库无法持久化。
  • 动态web

    提供给用户的数据始终会发生改变,每个人在不同的时间、不同的地点看到的信息各不相同,例如:

    • 几乎所用的网站:淘宝、京东……
      • 技术栈

        1. ASP:微软公司的,国内最早流行,页面业务代码极其混乱,维护成本高
        2. PHP:简单、功能强大、跨平台、开发速度快,局限性在于无法承载大访问量
        3. Servlet/JSP:sun公司主推B/S架构,基于Java语言,可承受三高(高并发、高可用、高性能),语法像ASP(加强市场强度)。
      • 优点

        1. 可以动态更新,所有用户看到的都不是同一个页面;
        2. 可以与数据库交互,实现数据持久化。
      • 缺点

        加入服务器的动态web资源出现了错误的时候,我们需要重写更正后台程序(甚至停机维护),重新发布。

1.3 web应用程序

​ web应用程序,即可以提供浏览器访问的程序。一个web应用程序应该由多部分组成(静态web、动态web):

  • html、css、js;
  • jsp、servlet;
  • java程序;
  • jar包;
  • 配置文件(properties、xml)。



1.4 web服务器

web服务器,即发布及运行Web应用的容器,只有将开发的Web项目放置到该容器中,才能使网络中的所有用户通过浏览器进行访问。开发Java Web应用所采用的服务器主要是与JSP/Servlet兼容的Web服务器,比较常见的有Tomcat、Resin、JBoss、WebSphere 和 WebLogic 等 。

  • Tomcat 服务器

    目前最为流行的Tomcat服务器是Apache-Jarkarta开源项目中的一个子项目,是一个小型、轻量级的支持JSP和Servlet 技术的Web服务器,因为Tomcat 技术先进、性能稳定,而且免费,所以也是初学者学习开发JSP应用的首选。Tomcat 实际上运行JSP页面和Servlet。Tomcat下载后有几个文件夹:

    • bin目录

      该目录下存放的是二进制可执行文件

      • 如果是安装版,那么这个目录下会有两个exe文件: tomcat9.exe、tomcat9w.exe,前者是在控制台下启动Tomcat,后者是弹出UGI窗口启动Tomcat;
      • 如果是解压版,那么会有startup.bat和shutdown.bat文件,startup.bat用来启动Tomcat,但需要JDK的配置,shutdown.bat用来停止Tomcat。
    • conf目录

      这是一个非常非常重要的配置文件目录,这个目录下有四个最为重要的文件:

      • server.xml配置整个服务器信息。例如修改端口号,添加虚拟主机等;
      • tomcat-users.xml存储tomcat用户的文件,这里保存的是tomcat的用户名及密码,以及用户的角色信息。可以按着该文件中的注释信息添加tomcat用户,然后就可以在Tomcat主页中进入Tomcat Manager 页面了;
      • web.xml部署描述符文件,这个文件中注册了很多MIME类型,即文档类型。这些MIME类型是客户端与服务器之间说明文档类型的,如用户请求一个html网页,那么服务器还会告诉客户端浏览器响应的文档是text/html类型的,这就是一个MIME类型。客户端浏览器通过这个MIME类型就知道如何处理它了。 当然是在浏览器中显示这个html文件了。但如果服务器响应的是一个exe文件,那么浏览器就不可能显示它,而是应该弹出下载窗⼝才对。MIME就是用来说明文档的内容是什么类型的
      • context.xml对所有应用的统一配置,通常我们不会去配置它。
    • lib目录

      Tomcat的类库,里面是一大堆jar文件。如果需要添加Tomcat依赖的jar文件,可以把它放到这个目录中,当然也可以把应用依赖的jar文件放到这个目录中,这个目录中的jar所有项目都可以共享之, 但这样你的应用放到其他Tomcat下时就不能再共享这个目录下的Jar包了,所以建议只把Tomcat需要的 Jar包放到这个目录下;

    • logs目录

      这个目录中都是日志文件,记录了Tomcat启动和关闭的信息,如果启动Tomcat时有错误,那么异常也会记录在日志文件中。

    • temp目录

      存放Tomcat的临时文件,这个目录下的东西可以在停下Tomcat后删除!

    • webapps目录

      存放web项目的目录,其中每个文件夹都是一个项目;如果这个目录下已经存在了目录,那么都是tomcat自带的项目。其中ROOT是一个特殊的项目,在地址栏中没有给出项目目录时,对应的就是ROOT项目。

      http://localhost:8080/examples,进入示例项目。其中examples就是项目名,即文件夹的名字。

    • work目录

      运行时生成的文件,最终运行的文件都在这里,通过webapps中的项目生成的!可以把这个目录下的内容删除,再次运行时会再次生成work目录。当客户端用户访问⼀一个JSP文件时,Tomcat会通过JSP生成Java文件,然后再编译Java文件生成class文件,生成的java和class文件都会存放到这个目录下。

      JSP本质上就是一个Servlet。

    • LICENSE:许可证。

    • NOTICE:说明文件。

  • Resin 服务器

    Resin是Caucho公司的产品,是一个非常流行的支持Servlet和JSP的服务器,速度非常快Resin本身包含了一个支持HTML的Web服务器,这使它不仅可以显示动态内容,而且显示静态内容的能力也毫不逊色,因此许多网站都是使用Resin服务器构建 。

  • JBoss服务器

    JBoss是一个遵从JavaEE规范的、开放源代码的、纯Java的EJB服务器,对于J2EE有很好的支持。 JBoss采用JML API实现软件模块的集成与管理,其核心服务器是提供EJB服务器,不包含Servlet和JSP的 Web容器,不过它可以和Tomcat完美结合

  • WebSphere 服务器

    WebSphere是IBM公司的产品,可进一步细分为 WebSphere Performance Pack、Cache Manager 和WebSphere Application Server等系列,其中WebSphere Application Server 是基于Java 的应用环境,可以运行于 Sun Solaris、Windows NT 等多种操作系统平台,用于建造、部署和管理 Internet和Intranet Web应用程序。

  • WebLogic 服务器

    WebLogic 是BEA公司的产品(现在已经被Oracle收购),可进一步细分为 WebLogic Server、 WebLogic Enterprise 和 WebLogic Portal 等系列,其中 WebLogic Server 的功能特别强大。WebLogic 支持企业级的、多层次的和完全分布式的Web应用,并且服务器的配置简单、界面友好。对于那些正在寻求能够提供Java平台所拥有的一切应用服务器的用户来说,WebLogic是一个十分理想的选择。


2. Http协议简介

2.1 基本概念

​ 超文本传输协议(HyperText Transfer Protocol,HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP是万维网的数据通信的基础。

​ HTTP的发展是由蒂姆·伯纳斯-李于1989年在欧洲核心研究组织(CERN)所发起。HTTP的标准制定由万维网协会(World Wide Web Consortium,W3C)和互联网工程任务组(Internet Engineering Task Force,IETF)进行协调,最终发布了一系列的RFC,其中最著名的是1999年6月公布的 RFC 2616,定义了HTTP协议中现今广泛使用的一个版本——HTTP 1.1

  • http1.0 时代

    • HTTP/1.0:客户端可以与web服务器连接后,只能获得一个web资源。
  • http2.0 时代

    • HTTP/1.1:客户端可以与web服务器连接后,可以获得多个web资源。
  • HTTP:是一个简单的请求-响应协议,默认端口为80,它通常运行在TCP之上。

  • Https:在HTTP 的基础上加入SSL(HTTP与TCP之间增加一个加密/身份验证层),更安全,默认端口是443

JavaWeb学习笔记:一文叙说Servlet、Session与Cookie、Servlet3.0注解、过滤器与监听器_第1张图片

2.2 网站的访问

下面以访问 www.baidu.com 为例

2.2.1 访问的简要过程
  1. 打开浏览器,输入网站的域名( www.baidu.com);

  2. DNS域名解析(将域名转换成对应的ip地址):

    1. 浏览器首先搜索浏览器自身缓存的DNS记录(不同的浏览器自定义的缓存时间不同),如果存在就返回;

    2. 如果浏览器缓存中没有找到需要的记录或记录已经过期,则搜索本地hosts文件;

       C:\Windows\System32\drivers\etc\hosts
      
    3. 如果在hosts文件中没有找到需要的记录或记录已经过期,则向域名解析服务器发送解析请求;

  3. 经过域名解析后,如果解析成功,会返回这个域名的ip地址给客户端(通常是浏览器),然后通过TCP三步握手建立连接;

  4. 客户端发送HTTP请求;

  5. 服务器解析请求报文,如果接受了,就定位请求资源,返回HTTP响应(将资源副本写到TCP套接字中,由客户端读取);

  6. 浏览器解析得到响应数据,进行浏览器渲染;

  7. 释放TCP连接。

注: 点击回顾TCP三步握手、四步挥手过程以及为什么要三步握手?

2.2.2 http请求

​ 客户端 --> 发送请求(Request) --> 服务器

2.2.2.1 请求行(General,不属于headers,只用于收集请求url和响应的status等信息)
Request URL:https://www.baidu.com/        //请求地址
Request Method:GET                        //get方法(⼋种请求⽅法)
Status Code:200 OK                        //状态码:200
Remote Address:14.215.177.39:443          //远程地址 ip:端口号

​ HTTP/1.1协议中共定义了八种请求方法(也叫“动作”)来以不同方式操作指定的资源:

  • GET(常用)

    向指定的资源发出显示请求。请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但高效。请求的数据会附加在URL之后,以?分割URL和传输数据,多个参数用&连接。URL的编码格式采用的是ASCII编码,而不是unicode,即是说所有的非ASCII字符都要编码之后再传输。

  • HEAD

    与GET方法一样,都是向服务器发出指定资源的请求。只不过服务器将不传回资源的本文部分。它的好处在于,使用这个方法可以在不必传输全部内容的情况下,就可以获取其中关于该资源的信息(元信息或称元数据)。

  • POST(常用)

    请求能够携带的参数没有限制,大小没有限制,不会在浏览器的URL地址栏显示数据内容,安全,但不高效

  • PUT

    向指定资源位置上传其最新内容。

  • DELETE

    请求服务器删除Request-URI所标识的资源。

  • TRACE

    回显服务器收到的请求,主要用于测试或诊断。

  • OPTIONS

    这个方法可使服务器传回该资源所支持的所有HTTP请求方法。用’*'来代替资源名称,向Web服务器发送 OPTIONS请求,可以测试服务器功能是否正常运作。

  • CONNECT

2.2.2.2 请求头(Request Headers)
Accept:text/html										//告诉服务器,它所支持的数据类型
Accept-Encoding:gzip, deflate, br          				//支持哪种编码格式 GBK UTF-8 GB2312 ISO8859-1
Accept-Language:zh-CN,zh;q=0.9 							//告诉服务器,它的语言环境
Cache-Control:max-age=0									//缓存控制
Connection:keep-alive									//告诉服务器,请求完成是断开还是保持连接,这里是长连接(从HTTP/1.1起,默认使长连接,即在保持时间内有效,由于TCP通信需要进行3次握手,所以可以建立一定程度上的持续性连接,减少进行3次握手的次数,提高通讯性能)
HOST:                                                  //主机

.....

2.2.3 Http响应
2.2.3.1 响应头(Response Headers)
Cache-Control: private									//缓存机制
Connection: keep-alive									//告诉浏览器,请求完成是断开还是保持连接
Content-Encoding: gzip									//告诉浏览器,它的编码格式
Content-Type: text/html;charset=utf-8					//内容类型

.....
2.2.3.2 响应状态码
  • 200:
    • 请求响应成功 200
    • ……
  • 3xx:请求重定向
    • 重定向:你重新到我给你新位置去;
    • ……
  • 4xx:找不到资源
    • 资源不存在 404;
    • ……
  • 5xx:
    • 服务器代码错误 500
    • 网关错误 502
    • ……

注: 点击查看更详细的状态码介绍


3. Servlet

3.1 什么是Servlet?

​ Servlet(Server Applet),全称Java Servlet,是用Java编写的服务器端程序,其主要功能在于交互式地浏览和修改数据,生成动态Web内容。Servlet运行于支持Java的应用服务器中。从实现上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。

​ 狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。


3.2 Servlet的工作模式

JavaWeb学习笔记:一文叙说Servlet、Session与Cookie、Servlet3.0注解、过滤器与监听器_第2张图片

  1. 客户端发送请求给服务器;
  2. 服务器启动并调用Servlet,Servlet根据客户端请求生成响应内容并将其传给服务器;
  3. 服务器将响应返回客户端。

3.3 开发Servlet的步骤

JavaWeb学习笔记:一文叙说Servlet、Session与Cookie、Servlet3.0注解、过滤器与监听器_第3张图片

  1. 编写一个类,实现Servlet接口或者继承HttpServlet都可;

    public class LoginServlet implements Servlet {
         @Override
         public void init(ServletConfig servletConfig) throws ServletException {
         	//初始化⽅法
         }
         @Override
         public ServletConfig getServletConfig() {
         	return null;
         }
         @Override
         public void service(ServletRequest servletRequest, ServletResponse
        	servletResponse) throws ServletException, IOException {
         	//处理get/post请求的⽅法
         }
         @Override
         public String getServletInfo() {
         	return null;
         }
         @Override
         public void destroy() {
         	//销毁的⽅法
         }
    }
    
  2. 在web.xml文档中配置映射关系;

    <servlet>
    	<servlet-name>自定义名称servlet-name>
    	<servlet-class>处理请求的类的完整路径servlet-class>
    servlet>
    
    <servlet-mapping>
    	<servlet-name>自定义名称,与上保持一致servlet-name>
    	<url-pattern>请求名url-pattern>
    servlet-mapping>
    
  3. 把开发好的java类部署到web服务器中。

注意:

  1. 一个Servlet可以指定一个甚至多个映射路径, 一个Servlet可以指定通用映射路径(*);
  2. 可以自定义后缀实现请求映射,但是*前面不能加项目映射的路径;
  3. 指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求;
  4. 例如:/user/.do、/.do、test*.do都是非法的,启动时候会报错

<servlet-mapping>
    <servlet-name>helloservlet-name>
    <url-pattern>/hello/*url-pattern>
servlet-mapping>


<servlet-mapping>
    <servlet-name>helloservlet-name>
    <url-pattern>/*url-pattern>
servlet-mapping>


<servlet-mapping>
    <servlet-name>helloservlet-name>
    <url-pattern>*.xurl-pattern>
servlet-mapping>



3.4 服务器程序处理请求的大致过程

  1. 页面发送请求(例如”test“);
  2. 服务器接受请求后,访问web.xml
  3. 请求(“test”)与servlet-mapping标签中url-pattern标签中的内容(/test)进行匹配;
  4. 匹配成功后,根据url-pattern标签对应的servlet-name去匹配servlet标签中的servlet-name;
  5. 再次匹配成功后,根据servlet标签中的servlet-class找到正确处理该请求的Servlet类的完整路径;
  6. 根据提交的请求方法去匹配对应的处理方法来处理这个请求(反射)。



3.5 Servlet工作原理

  1. Servlet接口定义了Servlet与Servlet容器之间的契约;

    这个契约是:Servlet容器将Servlet类载入内存,并产生Servlet实例和调用它具体的方法。

    但是要注意的是,在一个应用程序中,每种Servlet类型只能有一个实例(单例模式)

  2. 用户请求致使Servlet容器调用Servlet的service()方法,并传入一个ServletRequest对象和一个ServletResponse对象;

    ServletRequest对象和ServletResponse对象都是由Servlet容器(例如 TomCat)封装好的,并不需要程序员去实现,程序员可以直接使用这两个对象。

  3. ServletRequest中封装了当前的Http请求,ServletResponse表示当前用户的Http响应

    因此,开发人员不必解析和操作原始的Http数据;程序员只需直接操作ServletResponse对象就能把响应轻松的发回给用户。

  4. 对于每一个应用程序,Servlet容器还会创建一个ServletContext对象,它代表着当前的web应用

    ServletContext context = this.getServletContext();
    

    这个对象中封装了上下文 (应用程序)的环境详情,每个应用程序只有一个ServletContext,它的作用在于:

    1. 共享数据

      在这个Servlet中保存的数据,可以在另外一个servlet中拿到。

    2. 获取初始化参数

      context.getInitParameter("参数名")
      
    3. 请求转发

      context.getRequestDispatcher("请求转发的路径").forward(req,resp);
      
  5. 每个Servlet对象也都有一个封装 Servlet配置的ServletConfig对象。



3.6 Servlet的生命周期

JavaWeb学习笔记:一文叙说Servlet、Session与Cookie、Servlet3.0注解、过滤器与监听器_第4张图片

  1. 当客户端发送请求后,由容器(即web服务器,例如tomcat)去解析请求, 根据请求找到对应的servlet;

    即第3.4小节服务器程序处理请求过程的第六个步骤的扩展

  2. 判断该类的对象是否存在;

    1. 不存在则创建servlet实例,并调取init()方法进行初始化(即第一次进行这一步操作);
    2. 存在则不操作。
  3. 调取 service()方法,由service()方法判断客户端的请求方式,根据请求方式调用对应的处理方法(doget、dopost……);

  4. 将结果响应给客户端(至此单次请求处理完毕);

  5. 当服务器关闭时调取destroy()方法进行销毁。


3.7 请求Request

​ HttpServletRequest表示Http环境中的Servlet请求。它继承于ServletRequest类,扩展于javax.servlet.ServletRequest接口。

3.7.1 常用方法

无论前台页面传递的是什么类型的数据,后台都是使用String接收的

  • String getParameter(String name)

    根据表单组件名称获取提交数据,返回值是String,服务器在接收数据时使用字符串统一接收

  • String[ ] getParameterValues(String name)

    获取表单组件对应多个值时的请求数据。

  • void setCharacterEncoding(String charset)

    指定每个请求的编码。

    tomcat8 以后针对post请求才起作用,8以前get也要去设置一下防止乱码。

  • RequestDispatcher getRequestDispatcher(String path)

    返回一个RequestDispatcher对象,该对象的forward( )方法用于请求转发。

    request.getRequestDispatcher("../success.jsp").forward(request,response);
    
  • 存值,request.setAttribute(“key”,value);

    用于存值,单次请求有效,可以将数据返回给前端页面。

  • 取值,request.getAttribute(“key”);

    取值后需要向下转型(返回类型为Object)。

3.7.2 前端页面发送请求的方式
  1. 通过表单 get/post提交;

  2. 通过a标签发送数据(get提交);

    <a href="/login?a=10&name=abc&pass=123">
    
  3. 通过地址栏直接拼接-get请求;

  4. js提交数据-get请求。

    location.href="请求?key=value&key=value"
    
  5. ajax请求。



3.8 响应Response

​ 在Service API中,定义了一个HttpServletResponse接口,它继承子ServletResponse接口,门用来封装HTTP响应消息。 在HttpServletResponse接口中定义了向客户端发送响应状态码、响应消息头、响应消息体的方法

3.8.1 常用方法
  • void addCookie(Cookie var1)

    给这个响应添加一个cookie。

  • void sendRedirect(String var1)

    发送一条响应码,将浏览器跳转到指定的位置。

  • PrintWriter getWriter()

    获得字符流,通过字符流的write(String s)方法可以将字符串设置到 response 缓冲区中,随后Tomcat会将response缓冲区中的内容组装成Http响应返回给浏览器端。

  • void setContentType()

    设置响应内容的类型

3.8.2 请求转发与重定向区别

JavaWeb学习笔记:一文叙说Servlet、Session与Cookie、Servlet3.0注解、过滤器与监听器_第5张图片

JavaWeb学习笔记:一文叙说Servlet、Session与Cookie、Servlet3.0注解、过滤器与监听器_第6张图片




重定向:response.sendRedirect()

转发:request.getRequestDispatcher("…/success.jsp").forward(request,response);

  • 相同点

    • 都能实现页面跳转。
    • Session中的值都是不会丢失的。
  • 不同点

    • 重定向时地址栏会改变,request中存储的数据会丢失;转发时地址栏显示的是请求页面的地址,request数据可以保存
    • 转发属于一次请求一次响应,重定向属于两次请求(地址栏修改了两次)两次响应

  • 如何选择转发还是重定向?

    • 如果要操作到了request域中的数据,那么就只能使用转发;

    • 如果当前需要访问外部web应用程序的资源,那么就只能使用重定向;

    • 如果请求中有比较重要的数据,不能重复提交(比如提交表单),建议使用重定向;

      因为如果是使用转发,用户多次刷新页面可能导致同一数据多次提交,导致不必要的错误发生,而将当前页面重定向到另一个页面后,这个页面任意重新加载没有副作用。

    • 如果使用哪种方式都无所谓的话,建议使用转发。

      重定向的速度比转发慢,因为浏览器还得发出一个新的请求。


4. 会话

背景:request存的值只能在单次请求中保存,保存的数据不能跨页面;当重定向时,request存的值会丢失。

​ 通俗意义上来说,从打开浏览器到关闭浏览器,期间访问服务器就称为一次会话,因为默认关闭浏览器就会自动清除cookie。严谨地说,只要服务器端的session和客户端cookie都有效,且sessionIId能匹配上,就称为同一次会话

保存会话的两种技术(会话跟踪技术):cookie和session。



4.1 Session

​ Session通过在服务器端记录信息确定用户身份,Session的数据可以在多个页面中共享,即使重定向页面,数据也不会丢失,Session中可以包含n个request

4.1.1 常用方法
  • HttpSession getSession()

    获取Session对象。

  • void setAttribute(String key,Object value)

    以key/value的形式保存对象值,将数据存储在服务器端。

  • Object getAttribute(String key)

    通过key获取对象值。

  • void invalidate()

    设置session对象失效。

  • String getId()

    获取sessionId,当第一次登录成功后,Session会产生一个唯一的id,浏览器之后访问时如果发现id值还是之前id,那么说明当前访问的属于同一个会话。

  • void setMaxInactiveInterval(int interval)

    设定session的非活动时间,默认是30分钟,单位是秒。

  • int getMaxInactiveInterval()

    获取session的有效非活动时间(以秒为单位)。

  • void removeAttribute(String key)

    从session中删除指定名称(key)所对应的对象。

  • boolean isNew()

    判断session是否是新建的。

  • long getCreationTime()

    返回Session的创建日期。返回类型为long,常被转化为Date类型。


4.1.2 Session的生命周期
  • Session存储在哪?

    为了获得更高的存取速度,服务器一般把Session放在内存。每个用户都会有一个独立的Session。如果Session内容过于复杂,当大量客户访问服务器时可能会导致内存溢出。因此,Session里的信息应该尽量精简(只存重要的信息即可)。

  • Session什么时候创建?

    Session在用户第一次访问服务器的时候自动创建。需要注意只有访问JSP、Servlet等程序时才会创建 Session,只访问HTML、IMAGE等静态资源并不会创建Session。如果尚未生成Session,也可以使 request.getSession(true)强制生成Session。Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。用户每访问服务器一次,无论是否读写Session,服务器都认为该用户的Session活跃(active) 了一次。

  • Session什么时候删除?

    防止内存溢出,服务器会把长时间内没有活跃的Session从内存删除。这个时间就是Session的超时时间。如果超过了超时时间没访问过服务器,Session就自动失效了。

    1. 可以通过对应的setMaxInactiveInterval方法对保持时间进行设置;

    2. 可以在web.xml文件中进行设置。

      <session-config>
      	<session-timeout>30session-timeout>
      session-config>
      



4.2 Cookie

​ Cookie通过在客户端记录信息确定用户身份, Cookie是客户端(一般指浏览器)请求服务器后,服务器发给客户端的一个辨认标识,保存在客户端,当客户端再次向服务器发送请求时,会携带着这个辨认标识,服务器就可以通过这个标识来识别客户端的身份或状态等。

4.2.1 Cookie的常见作用
  1. 保持登录

    将用户的信息保存到Cookie中,并发送给浏览器,并且将有效时间设置为一个较长的时间(默认是关闭浏览器就清除Cookie),这样浏览器在以后访问网站时,都会带着该Cookie,服务器以此来辨识用户,用户就不再需要输入用户名和密码等信息。

  2. 记录用户名

    一旦用户登录成功以后,下次再登录时,直接将Cookie中的用户名读取并显示出来,这样用户就不需要再次输入用户名,只输入密码即可(浏览器已经自动实现)。

4.2.2 Cookie的设置、获取以及有效时间
  1. 通过HttpServletResponse.addCookie的方式设置Cookie

    Cookie cookie = new Cookie("key","value");
    response.addCookie(cookie);//如果是我们创建sseion的时候,其实服务器隐含了帮我们把SessionId存进cookie并携带响应了
    
  2. 服务端通过HttpServletRequest获取客户端携带的cookie

    Cookie[] cookies = request.getCookies();
    String value ="";
    if(cookies != null)
        for(Cookie c : cookies){
            String name = c.getName();//获取Cookie名称key
            if("key".equals(name)){
                value = c.getValue();//获取Cookie的值value
                break;
            }
        }
    
  3. Cookie的有效时间

    //setMaxAge⽤来设置Cookie的最⼤有效时间,需要int型的参数,代表有效的秒数
     cookie.setMaxAge(秒数)//(1)会话Cookie,即在当前会话有效,退出浏览器后会话Cookie自动清除
     //当参数小于0时,和不设置是一样的(即等价于默认设置)
     cookie.setMaxAge(-100);
    
     //当参数等于0时,浏览器不会保存Cookie,Cookie立即失效(可以看作是删除Cookie)
     cookie.setMaxAge(0);
    
    //(2)持久Cookie/硬盘Cookie,在保持时间内持久性存储到用户的硬盘中,直到过期后清除。
     //当参数大于0时,会设置为指定的秒数
     cookie.setMaxAge(30);
    



4.3 Session与Cookie的区别

Session技术是依赖于Cookie技术的, Session是由应用服务器维持的一个服务器端的存储空间,用户在连接服务器时,会由服务器生成一个唯一的SessionID,并使用该SessionID 作为标识符来存取服务器端的Session存储空间。之后,SessionID这一数据则会响应到客户端,用Cookie保存的,用户提交请求时,会将这一SessionID提交到服务器端来存取 Session数据。

一旦客户端禁用Cookie,那么Session也会失效(就像钥匙和锁,钥匙都没了,也就找不到对应的锁了,Session技术也就没用了)。

  • Session(底层是基于Cookie实现的)
    • Session把用户的数据写到用户独占Session中,服务器端保存 ,相对安全一些;

    • Session对象由服务器创建;

    • Session可以保存很多数据,但是过多会导致内存溢出;

      因为通常是存在服务器的内存里,所以一般只用来保存重要的信息,减少服务器资源的浪费

    • Session调用特有方法设置保持时间,时间一过即失效。

  • Cookie
    • Cookie是把用户的数据写给用户的浏览器,浏览器保存,相对不安全一些;
    • 一个Cookie只能保存一个信息(不超过4kb),一个web站点可以给浏览器发送多个cookie(大多数浏览器限制一个站点最多存放20个cookie)
    • 不设置有效期(会话Cookie默认在关闭浏览器后自动失效,设置了的话会保存到硬盘里);
    • 设置有效期时间为 0 (不保存)。


5. 设置与获取初始化参数

5.1 局部初始化参数

  1. 在web.xml中,直接在某一Servlet标签中配置参数,只对当前Servlet的处理有效

    <servlet>
         <servlet-name>名称servlet-name>
         <servlet-class>路径servlet-class>
         <init-param>
     	    <param-name>encodingparam-name>
     	    <param-value>utf-8param-value>
         init-param>
    servlet>
    
  2. servlet中获得初始化参数,重写init()方法

    public void init(ServletConfig config) throws ServletException {
    	encoding= config.getInitParameter("encoding");
    }
    

5.2 全局初始化参数

  1. 在web.xml中,context-param标签与servlet标签同级,单独添加这样的一个标签并配置参数,可以对所有servlet的处理有效

    <context-param>
    	<param-name>参数名param-name>
        <param-value>参数值param-value>
    context-param>
    
  2. 获得数据

    // 请求->init()->service()->doget/dopost->destory();
    @Override 
    public void init(ServletConfig config) throws ServletException {
    	参数名=config.getServletContext().getInitParameter("参数名");
    }
    

5.3 会话失效时间

​ web.xml中设置。


<session-config>
	
	<session-timeout>15session-timeout>
session-config>


6. Servlet3.0注解

​ 从Servlet3.0开始,配置Servlet支持注解方式(Servlet类上使用@WebServlet注解进行配置),但还是保留了配置web.xml方式。

​ 下例是通过注解方式配置,web.xml中不需要配置该Servlet,相当于把xml里该配置的东西通过注解的方式搬过来了。

@WebServlet(name = "myUserServlet",
    urlPatterns = "/user/test",   
    loadOnStartup = 1,          
    initParams = {
    	@WebInitParam(name="name", value="啊明"),
    	@WebInitParam(name="pwd", value="123456")
    }
)
public class UserServlet extends HttpServlet {
	//……
}
  • @WebServlet

    属性 类型 是否必选 使用说明
    name String 指定Servlet名称
    urlPatterns/value String[] 这两个属性作用相同,指定Servlet处理的url,斜杠必须,可以多个
    loadOnStartup int 标记容器是否在应用启动时就加载这个 Servlet,等价于配置文件中的标签,0或正数代表应用启动时就加载这个 Servlet,正数越小优先级越高
    initParams webInitParam[] 配置初始化参数
    displayName String 指定Servlet显示名称
    asyncSupported boolean 指定Servlet是否支持异步操作模式
  • @WebInitParam

    属性 类型 使用说明
    name String 指定参数名称
    value String 指定参数对应值

7. 过滤器Filter

7.1 过滤器的概念

​ 过滤器实际上就是对web资源进行拦截,做一些处理后再交给下一个过滤器或Servlet处理,通常都是用来拦截request进行处理的,也可以对返回的response进行拦截处理。

JavaWeb学习笔记:一文叙说Servlet、Session与Cookie、Servlet3.0注解、过滤器与监听器_第7张图片

7.2 过滤器的使用

  1. 创建一个类实现Filter接口

    public class CharSetFilter implements Filter{}
    
  2. 重写接口中的方法

    public void destroy() { 
        //销毁的方法
    }
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //过滤方法 主要是对request和response进行一些处理,然后交给下一个过滤器,没有下一个了就交给Servlet处理
        chain.doFilter(req, resp);//执行过滤器链
    }
    public void init(FilterConfig config) throws ServletException {
        /*服务器一启动就会执行初始化方法(单例模式) 接收一个FilterConfig类型的参数 该参数是对Filter的一些配置*/
    }
    
  3. 在web.xml文件中配置

    使用多个过滤器的时候,web.xml中的配置顺序就是过滤器执行的顺序。(先执行的过滤器最后结束,和递归return一样)

    <filter>
        <filter-name>过滤器名称filter-name>
        <filter-class>过滤器所在的路径filter-class>
    filter>
    <filter-mapping>
        <filter-name>过滤器名称filter-name>
        <url-pattern>需要过滤的资源url-pattern>
    filter-mapping>
    

7.3 过滤器的生命周期

​ 程序启动时调用Filter的init()方法(唯一 一次),程序停止时调用Filter的destroy()方法(唯一 一次),doFilter()方法每次的访问请求如果符合拦截条件都会调用。

​ 如果是程序第一次运行,会在servlet调用init()方法以后调用;不管第几次,都在调用doGet(),doPost()方法之前。同时,过滤器的生命周期可以类比一下servlet的生命周期。


7.4 过滤器使用场景

  • 防止用户未登录就执行后续操作
  • 设置编码方式
  • 非法文字筛选
  • 下载资源的限制
  • 可以在servlet之前和之后执行特定的操作
  • ……

8. 监听器Listener

8.1 监听器的相关概念

  • 事件源:

    被监听的对象(三个域对象 request、session、servletContext) 。

  • 监听器:

    监听器就是监听某个域对象的的状态变化的组件,监听事件源对象、事件源对象的状态的变化都会触发监听器。

  • 注册监听器:

    将监听器与事件源进行绑定 。

  • 响应行为:

    监听器监听到事件源的状态变化时所涉及的功能代码(程序员编写代码)。


8.2 监听器的分类

JavaWeb学习笔记:一文叙说Servlet、Session与Cookie、Servlet3.0注解、过滤器与监听器_第8张图片

  • ServletContext域
    • 监听域对象的创建与销毁:ServletContextListener;
      • 初始化的工作:初始化对象、初始化数据(加载数据库驱动、连接池的初始化)
    • 监听域对象的属性变化:ServletContextAttributeListener。
  • HttpSession域
    • 监听域对象的创建与销毁:HttpSessionListener;
    • 监听域对象的属性变化:HttpSessionAttributeListener。
  • ServletRequest域
    • 监听域对象的创建与销毁:ServletRequestListener;
    • 监听域对象的属性变化:ServletRequestAttributeListener。

8.3 监听器的使用(以HttpSession域的监听器为例)

  1. 编写一个监听器类去实现监听器接口

    //监听创建和销毁
    public class SessionListener implements HttpSessionListener{}
    //监听操作域对象的属性
    public class SessionListener implements HttpSessionAttributeListener{}
    
  2. 实现对应监听器的方法

    //监听创建和销毁
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent){
        //代码
    }
    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent){
        //代码
    }
    
    //监听操作域对象的属性
    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent){//增加
        //代码
    }
    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent){//删除
        //代码
    }
    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent){//更改
        //代码
    }
    
  3. 在web.xml中进行配置

    <listener>
    	<listener-class>监听器所在的路径listener-class>
    listener>
    

8.4 监听器的生命周期与作用

  1. ServletContext域
  2. 生命周期
    • 何时创建:服务器启动创建
    • 何时销毁:服务器关闭销毁
    • contextInitialized在容器启动时被调用(在ServletContext被实例化后执行);
    • contextDestroyed 在容器销毁时调用(在ServletContext被销毁前执行)。
  3. 主要作用
    • 初始化的工作:初始化对象、初始化数据(加载数据库驱动、连接池的初始化)
    • 加载一些初始化的配置文件(spring的配置文件)
    • 任务调度(定时器—Timer/TimerTask)
    • 统计网站访问量
    • ……
  4. HttpSession域
  5. 生命周期
    • 何时创建:第一次用request.getSession时创建
    • 何时销毁:服务器关闭销毁、session过期、手动销毁
    • sessionCreated 在HttpSession创建后调用;
    • sessionDestroyed 在HttpSession销毁前调用。
  6. 主要作用
    例如,由于每次访问网站都会默认创建session对象(jsp开头的page指令中的session属性默认为 true,即被访问时创建session),可以以于计数网站在线的人。
  7. ServletRequest域
  8. 生命周期
    • requestDestroyed 在request对象创建后调用(发起请求);
    • requestInitialized 在request对象销毁前调用(请求结束)。
  9. 主要作用:监听每次请求中的创建、增删改、销毁。

9. Servlet、过滤器Filter、监听器Listener加载的先后顺序

JavaWeb学习笔记:一文叙说Servlet、Session与Cookie、Servlet3.0注解、过滤器与监听器_第9张图片

参考文章:
https://blog.csdn.net/wang_shuyu/article/details/53572046
https://www.cnblogs.com/caijh/p/7683007.html

  1. 服务器启动;
  2. 服务器创建ServletContext对象;
  3. 创建监听器对象(监听器对象的创建顺序按照配置顺序依次往下);
  4. ServletContextListener执行contextInitialized()方法;
  5. 创建过滤器对象(过滤器对象的创建顺序按照配置顺序依次往下);
  6. 创建Servlet对象(设置了服务器启动就创建的Servlet)
  7. ---------------------------开始请求(1-n)------------------------------------
  8. 每次请求,服务器会创建一个Request对象;
  9. ServletRequestListener执行requestInitialized()方法;
  10. 第一次被访问到的、还没有创建实例的Servlet进行实例化并执行init()方法;
  11. 过滤器链开始执行;
  12. 创建Session对象;
  13. HttpSessionListener执行sessionCreated()方法;
  14. 执行Servlet中的service()方法(doPost、doGet……);
  15. 过滤器链执行完毕;
  16. ServletRequestListener执行requestDestroyed()方法;
  17. Request对象销毁;
  18. ---------------------------请求结束-----------------------------------
  19. 过滤器对象销毁;
  20. ServletContextListener执行contextDestroyed()方法;
  21. ServletContext对象销毁;
  22. 服务器关闭。

注意:
(1)ServletContextAttributeListener、HttpSessionAttributeListener、ServletRequestAttributeListener只有触发对应操作时执行对应监听方法;
(2)注意session的是否销毁(时间到期、手动销毁),不然不会看到HttpSessionListener执行对应的监听销毁的方法。


web.xml中的加载顺序:context-param -> ServletContext -> Listener -> Filter -> Servlet 详细介绍

你可能感兴趣的:(JavaWeb,java,web,过滤器,servlet)