JavaWeb

本文详细介绍了JavaWeb的基本概念、web服务器分类、Servlet的生命周期和服务映射、HttpServlet和ServletConfig接口,以及过滤器、Session和Cookie的使用。通过实例解释了动态web和静态web的区别,探讨了JSP的工作原理和MVC架构。同时,还涵盖了Servlet事件监听器在Web应用中的角色。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


集合多天关于JavaWeb开发的学习笔记。利用Servlet开发web应用程序很高效。接下来将学习使用Spring MVC开发web应用程序。

基本概念

  • web开发
    • web就是网页的意思,如www.baidu.com
    • 静态web
      • html,css
      • 提供给所有人看的数据始终不会发生变化
    • 动态web
      • 淘宝,几乎是所有网站
      • 提供给所有人看的数据始终会发生变化,每个人在不同时间,不同地点看到的网页信息各不相同
      • 技术栈:Servlet/JSP,ASP,PHP
  • 在Java中,动态web资源开发的技术统称为JavaWeb
  • web应用程序:可以提供浏览器访问的程序
    • xxx.html…多个web资源,这些资源可以被外界访问,对外界提供服务
    • 我们能访问到的任何一个页面或者资源,都存在于这个世界上某一台计算机上
    • 统一的web资源会被放在同一个文件夹下,web应用程序–>Tomcat服务器
    • 一个web应用由多个部分组成(静态web,动态web)
      • html,css,js
      • jsp,servlet
      • Java程序
      • jar包
      • 配置文件(properties)
    • web应用程序编写完毕后,若想提供给外界访问,需要一个服务器来统一管理
  • 静态web
    • *.htm,*.html
    • 静态web缺点
      • web页面无法动态更新,所有用户看到的都是同一个页面
        • 轮播图,点击特效:伪动态
        • JavaScript:实际开发使用最多
        • VBScript
      • 无法和数据库交互(数据无法持久化,用户无法交互)
  • 动态web
    • 页面会动态展示,web页面的展示效果因人而异
    • 优点
      • web页面可以动态更新,提供多样化服务
      • 可以于数据库交互(数据持久化:注册,商品信息,用户信息…)
    • 缺点
      • 若服务器的动态web资源发生错误,需要重新编写后台程序,停机维护,重新发布

web服务器

分类

  • ASP

    • 微软:国内最早流行的服务器
    • 在HTML嵌入VB脚本,ASP+COM
    • 在ASP开发中,基本一个页面都有几千行业务代码,页面及其混乱
    • 维护成本高
    • C#
  • PHP

    • PHP开发速度很快,功能很强大,跨平台,代码简单
    • 无法承担大访问量
  • JSP/Servlet

    • sun公司主推的B/S架构
    • 基于Java语言(所有大公司,或者一些开源组件,都是用Java写的)
    • 可以承载三高问题带来的影响
    • 语法像ASP
  • IIS

    • 微软windows自带
  • Tomcat

    • 实际上运行JSP页面和Servlet
    • 免费开源web服务器,属于轻量级应用服务器
    • 在中小型系统和并发用户不多的场合下被普遍使用
    • 开发和调试JSP程序的首选
    • JavaWeb初学者最佳选择

网站结构

  • JavaWeb网站结构
|--RootDir :Tomcat服务器的web目录
	|--webapp:网站目录名
		|--WEB-INF
			|--classes:Java程序
			|--lib:web应用所依赖的jar包
			|--web.xml:网站配置文件
		|--index.html:默认首页
		|--static
			|--css
				|--style.css
			|--js
			|--img
		|--......

Servlet

Servlet简介

  • Servlet(Server Applet)是 Java Servlet 的简称,是使用 Java 语言编写的运行在服务器端的程序。具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容
  • 通常来说,Servlet 是指所有实现了 Servlet 接口的类
  • Servlet 主要用于处理客户端传来的 HTTP 请求,并返回一个响应,它能够处理的请求有 doGet() 和 doPost() 等
  • Servlet 由 Servlet 容器提供,Servlet 容器是指提供了 Servlet 功能的服务器(如 Tomcat)
  • Servlet 容器会将 Servlet 动态加载到服务器上,然后通过 HTTP 请求和 HTTP 应与客户端进行交互
  • Servlet 应用程序的体系结构如下图所示
    在这里插入图片描述
  • Servlet 的请求首先会被 HTTP 服务器(如 Apache)接收,HTTP 服务器只负责静态 HTML 页面的解析,而 Servlet 的请求会转交给 Servlet 容器Servlet 容器会根据 web.xml 文件中的映射关系,调用相应的 Servlet,Servlet 再将处理的结果返回给 Servlet 容器,并通过 HTTP 服务器将响应传输给客户端
  • Servlet技术特点
    • 方便
      • Servlet 提供了大量的实用工具例程,如处理很难完成的 HTML 表单数据、读取和设置 HTTP 头,以及处理 Cookie 和跟踪会话等
    • 跨平台
      • Servlet 使用 Java 类编写,可以在不同的操作系统平台和不同的应用服务器平台运行
    • 灵活性和可扩展性强
      • 采用 Servlet 开发的 Web 应用程序,由于 Java 类的继承性及构造函数等特点,使得应用灵活,可随意扩展
    • 除了上述几点以外,Servlet 还具有功能强大、能够在各个程序之间共享数据、安全性强等特点

Servlet相关接口和类

  • Servlet 接口中定义了 5 个抽象方法
    在这里插入图片描述
    其中 init()、service() 和 destroy() 方法可以表现 Servlet 的生命周期,它们会在某个特定的时刻被调用

  • Servlet 的接口有两个默认的接口实现类:GenericServlet 和 HttpServlet

    • GenericServlet 是一个抽象类,该类为 Servlet 接口提供了部分实现,它并没有实现 HTTP 请求处理
    • HttpServlet 是 GenericServlet 的子类,它继承了 GenericServlet 的所有方法,并且为 HTTP 请求中的 GET 和 POST 等类型提供了具体的操作方法。通常情况下,编写的 Servlet 类都继承自 HttpServlet,在开发中使用的也是 HttpServlet 对象
  • HttpServlet 类中包含两个常用方法
    在这里插入图片描述

  • HttpServlet 主要有两大功能,具体如下

    • 根据用户请求方式的不同,定义相应的 doXxx() 方法处理用户请求。例如,与 GET 请求方式对应的 doGet() 方法,与 POST 方式对应的 doPost() 方法
    • 通过 service() 方法将 HTTP 请求和响应分别强转为 HttpServletRequest 和 HttpServletResponse 类型的对象
  • 需要注意的是,由于 HttpServlet 类在重写的 service() 方法中,为每一种 HTTP 请求方式都定义了对应的 doXxx() 方法,因此,当定义的类继承 HttpServlet 后,只需要根据请求方式重写对应的 doXxx() 方法即可,而不需要重写 service() 方法

Servlet生命周期

  • Servlet声明周期如下图
    在这里插入图片描述

  • 按照功能的不同,大致可以将 Servlet 的生命周期分为三个阶段,分别是初始化阶段、运行阶段和销毁阶段

    • 初始化阶段

      • 当客户端向 Servlet 容器发出 HTTP 请求要求访问 Servlet 时,Servlet 容器首先会解析请求,检查内存中是否已经有了该 Servlet 对象,如果有,则直接使用该 Servlet 对象,如果没有,则创建 Servlet 实例对象,然后通过调用 init() 方法实现 Servlet 的初始化工作。需要注意的是,在 Servlet 的整个生命周期内,它的 init() 方法只能被调用一次
    • 运行阶段

      • 这是 Servlet 生命周期中最重要的阶段,在这个阶段中,Servlet 容器会为这个请求创建代表 HTTP 请求的 ServletRequest 对象和代表 HTTP 响应的 ServletResponse 对象,然后将它们作为参数传递给 Servlet 的 service() 方法
      • service() 方法从 ServletRequest 对象中获得客户请求信息并处理该请求,通过 ServletResponse 对象生成响应结果
      • 在 Servlet 的整个生命周期内,对于 Servlet 的每一次访问请求,Servlet 容器都会调用一次 Servlet 的 service() 方法,并且创建新的 ServletRequest 和 ServletResponse 对象,也就是说,service() 方法在 Servlet 的整个生命周期中会被调用多次
    • 销毁阶段

      • 当服务器关闭或 Web 应用被移除出容器时,Servlet 随着 Web 应用的关闭而销毁。在销毁 Servlet 之前,Servlet 容器会调用 Servlet 的 destroy() 方法,以便让 Servlet 对象释放它所占用的资源。在 Servlet 的整个生命周期中,destroy() 方法也只能被调用一次
  • 需要注意的是,Servlet 对象一旦创建就会驻留在内存中等待客户端的访问,直到服务器关闭或 Web 应用被移除出容器时,Servlet 对象才会销毁

Servlet配置虚拟路径映射

  • 在 web.xml 文件中,一个 <servlert-mapping> 元素用于映射一个 Servlet 的对外访问路径,该路径也称为虚拟路径
  • 创建好的 Servlet 只有映射成虚拟路径,客户端才能对其进行访问

Servlet多重映射

  • Servlet 的多重映射指同一个 Servlet 可以被映射成多条虚拟路径。也就是说,客户端可以通过多条路径实现对同一个 Servlet 的访问。Servlet 实现多重映射的两种方式:
    • 配置多个 <servlet-mapping> 元素
      <servlet-mapping>
          <!-- 映射为Test01 -->
          <servlet-name>TestServlet01</servlet-name>
          <url-pattern>/Test01</url-pattern>
      </servlet-mapping>
      
      <servlet-mapping>
          <!-- 映射为TestServlet01-->
          <servlet-name>TestServlet01</servlet-name>
          <url-pattern>/TestServlet01</url-pattern>
      </servlet-mapping>
      
      可以通过浏览器输入地址http://localhost:8080/dmeo/Test01和http://localhost:8080/dmeo/TestServlet01访问同一个servlet对象
    • 配置多个 <url-pattern> 子元素
      <servlet-mapping>
          <!-- 映射为TestServlet01和Test01 -->
          <servlet-name>TestServlet01</servlet-name>
          <url-pattern>/TestServlet01</url-pattern>
          <url-pattern>/Test01</url-pattern>
      </servlet-mapping>
      

Servlet映射路径中使用通配符

  • 在实际开发过程中,开发者有时会希望某个目录下的所有路径都可以访问同一个 Servlet,这时,可以在 Servlet 映射的路径中使用通配符*。通配符的格式有两种,具体如下。
    • 格式为“*.扩展名”,例如 *.do 匹配以 .do 结尾的所有 URL 地址
    • 格式为 /*,例如 /abc/* 匹配以 /abc 开始的所有 URL 地址
  • 以上两种通配符的格式不能混合使用。例如,/abc/*.do 是不合法的映射路径
  • 另外,当客户端访问一个 Servlet 时,如果请求的 URL 地址能够匹配多条虚拟路径,那么 Tomcat 将采取最具体匹配原则查找与请求 URL 最接近的虚拟映射路径

默认Servlet

  • 如果某个 Servlet 的映射路径仅仅是一个正斜线(/),那么这个 Servlet 就是当前 Web 应用的默认 Servlet
  • Servlet 服务器在接收到访问请求时,如果在 web.xml 文件中找不到匹配的 <servlet-mapping> 元素的 URL,则会将访问请求交给默认 Servlet 处理,也就是说,默认 Servlet 用于处理其他 Servlet 都不处理的访问请求
  • 配置默认Servlet
    <servlet>
        <servlet-name>DefaultServlet</servlet-name>
        <servlet-class>com.xxx.servlet.DefaultServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>DefaultServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    

Servlet Config接口

  • 在运行 Servlet 程序时,可能需要一些辅助信息,例如,文件使用的编码、使用 Servlet 程序的共享信息等,这些信息可以在 web.xml 文件中使用一个或多个 <init-param> 元素进行配置

  • 当 Tomcat 初始化一个 Servlet 时,会将该 Servlet 的配置信息封装到 ServletConfig 对象中,此时可以通过调用 init(ServletConfig config)方法将 ServletConfig 对象传递给 Servlet

  • ServletConfig接口的常用方法
    在这里插入图片描述

  • 参数信息配置代码

    <servlet>
      <servlet-name>ServletDemo</servlet-name>
      <servlet-class>com.demo.servlet.ServletDemo</servlet-class>
      <init-param>
          <param-name>encoding</param-name>
          <param-value>UTF-8</param-value>
      </init-param>
    </servlet>
    <servlet-mapping>
      <servlet-name>ServletDemo</servlet-name>
      <url-pattern>/ServletDemo</url-pattern>
    </servlet-mapping>
    

Servlet Context接口

  • 当 Tomcat 启动时,Tomcat 会为每个 Web 应用创建一个唯一的 ServletContext 对象代表当前的 Web 应用该对象封装了当前 Web 应用的所有信息。可以利用该对象获取 Web 应用程序的初始化信息、数据共享、读取资源文件等

获取 Web 应用程序的初始化参数

  • 在 web.xml 文件中,配置整个 Web 应用的初始化信息
    <context-param>
        <param-name>XXX</param-name>
        <param-value>xxx</param-value>
    </context-param>
    <context-param>
        <param-name>yyy</param-name>
        <param-value>yyy</param-value>
    </context-param>
    
    <context-param> 元素位于根元素 <web-app> 中,它的子元素 <param-name> 和 <param-value> 分别用于指定参数的名字和参数值。要想获取这些参数名和参数值的信息,可以使用 ServletContext 接口中定义的 getInitParameterNames()getInitParameter(String name)方法分别获取

在不同Servlet中进行数据通信

  • 可以在一个Servlet中通过getServletContext方法获得web应用中唯一的context对象
  • Servlet可以通过context对象的setAttribute方法,设定参数名和参数值,并保存在context中
  • 另一个Servlet同样可以通过getServletContext方法获得context对象,并通过context对象的getAttribute方法获得另一个Servlet设定的参数值

读取 Web 应用下的资源文件

  • 在实际开发中,有时会需要读取 Web 应用中的一些资源文件,如配置文件和日志文件等。为此,在 ServletContext 接口中定义了一些读取 Web 资源的方法,这些方法是依靠 Servlet 容器实现的
  • Servlet 容器根据资源文件相对于 Web 应用的路径,返回关联资源文件的 I/O 流资源文件在系统的绝对路径
  • ServletContext 接口中用于获取资源路径的相关方法
    在这里插入图片描述

Servlet处理用户请求的完整流程

  • 针对 Servlet 的每次请求,Web 服务器在调用 service() 方法之前,都会创建 HttpServletRequest 和 HttpServletResponse 对象
  • HttpServletRequest 对象用于封装 HTTP 请求消息,简称 request 对象
  • HttpServletResponse 对象用于封装 HTTP 响应消息,简称 response 对象
  • 浏览器访问Servlet过程
    在这里插入图片描述
    • 首先浏览器向 Web 服务器发送了一个 HTTP 请求,Web 服务器根据收到的请求,会先创建一个 HttpServletRequest 和 HttpServletResponse 对象,然后再调用相应的 Servlet 程序
    • 在 Servlet 程序运行时,它首先会从 HttpServletRequest 对象中读取数据信息,然后通过 service() 方法处理请求消息,并将处理后的响应数据写入到 HttpServletResponse 对象中。最后,Web 服务器会从 HttpServletResponse 对象中读取到响应数据,并发送给浏览器
  • 在 Web 服务器运行阶段,每个 Servlet 都只会创建一个实例对象针对每次 HTTP 请求,Web 服务器都会调用所请求 Servlet 实例的 service(HttpServletRequest request,HttpServletResponse response)方法,并重新创建一个 request 对象和一个 response 对象

HttpServlerRequest

HttpServlerResponse

请求转发

  • 当一个 Web 资源收到客户端的请求后,如果希望服务器通知另外一个资源处理请求,那么这时可以通过 RequestDispatcher 接口的实例对象实现。ServletRequest 接口中定义了一个获取 RequestDispatcher 对象的方法

    方法功能
    RequestDispatcher getRequestDispatcher(String path)返回封装了某条路径所指定资源的 RequestDispatcher 对象。其中,参数 path 必须以“/”开头,用于表示当前 Web 应用的根目录。需要注意的是,WEB-INF 目录中的内容对 RequestDispatcher 对象也是可见的。因此,传递给 getRequestDispatcher(String path) 方法的资源可以是 WEB-INF 目录中的文件
  • 获取到 RequestDispatcher 对象后,最重要的工作就是通知其他 Web 资源处理当前的 Servlet 请求,为此,RequestDispatcher 接口定义了两个相关方法

    方法功能
    forward(ServletRequest request,ServletResponse response)该方法用于将请求从一个 Servlet 传递给另一个 Web 资源。在 Servlet 中,可以对请求做一个初步处理,然后通过调用这个方法,将请求传递给其他资源进行响应。需要注意的是,该方法必须在响应提交给客户端之前被调用,否则将抛出 IllegalStateException 异常
    include(ServletRequest request,ServletResponse response)该方法用于将其他的资源作为当前响应内容包含进来
  • 在 Servlet 中,如果当前 Web 资源不想处理请求,则可以通过 forward() 方法将当前请求传递给其他的 Web 资源进行处理,这种方式称为请求转发
    在这里插入图片描述

  • 当客户端访问 Servlet1 时,可以通过 forward() 方法将请求转发给其他 Web 资源,其他 Web 资源处理完请求后,直接将响应结果返回到客户端

  • 浏览器地址栏中显示的仍然是访问Servlet1的请求路径,但是浏览器却显示出了Servlet2中要输出的内容。这是因为请求转发是发生在服务器内部的行为,从 Servlet1到 Servlet2属于一次请求,在一次请求中是可以使用 request 属性(set,getAttribute)进行数据共享

重定向

  • 在某些情况下,针对客户端的请求,一个 Servlet 类可能无法完成全部工作。这时,可以使用请求重定向完成这一工作

  • 请求重定向指 Web 服务器接收到客户端的请求后,可能由于某些条件的限制,不能访问当前请求 URL 所指向的 Web 资源,而是指定了一个新的资源路径,让客户端重新发送请求

  • 为了实现请求重定向,HttpServletResponse 接口定义了一个 sendRedirect()方法,该方法用于生成 302 响应码和 Location 响应头,从而通知客户端重新访问 Location 响应头中指定的 URL
    在这里插入图片描述

  • 重定向方法

    public void sendRedirect(java.lang.String location) throws java.io.IOException
    

    参数 location 可以使用相对 URL,Web 服务器会自动将相对 URL 翻译成绝对 URL,再生成 Location 头字段

  • 重定向与请求转发的区别

    • 请求转发是服务器内部行为,url地址不会发生变化,浏览器只对服务器进行一次访问
    • 重定向url地址会发生变化,浏览器对服务器进行两次访问

中文乱码问题解决方法

  • 由于计算机中的数据都是以二进制形式存储的,因此,当传输文本数据时,会发生字符和字节之间的转换。字符与字节之间的转换是通过查码表完成的,将字符转换成字节的过程称为编码,将字节转换成字符的过程称为解码,如果编码和解码使用的码表不一致,则会导致乱码问题

  • Request中文乱码问题以及解决方案

    • 在 HttpServletRequest 接口中提供了一个 setCharacterEncoding() 方法,该方法用于设置 request 对象的解码方式
      request.setCharacterEncoding("utf-8");  //设置request对象的解码方式
      
    • 需要注意的是,这种解决乱码的方式只对 POST 方式有效,而对 GET 方式无效
    • 为了解决 GET 方式提交表单时出现的中文乱码问题,可以先使用错误码表 ISO-8859-1 将用户名重新编码,然后使用码表 UTF-8 进行解码
      name = new String(name.getBytes("iso8859-1"),"utf-8");
      
  • Response中文乱码问题以及解决方案

    • 方式一
      response.setCharacterEncoding("utf-8");    //设置 HttpServletResponse使用utf-8编码
      response.setHeader("Content-Type", "text/html;charset=utf-8");    //通知浏览器使用utf-8解码
      
    • 方式二
      response.setContentType("text/html;charset=utf-8");    //包含第一种方式的两个功能
      
  • 使用URL编码解码方式

    URLEncoder.encode("中文", "utf-8")
    URLDecoder.decode(stringName, "utf-8")
    

Cookie

  • Cookie常用方法

    Cookie[] cookies = req.getCookies();    // 返回cookie数组,cookie可能有多个
    cookie.getName() // 获得cookie的名字
    cookie.getValue() // 获得cookie的值
    Cookie ck = new Cookie("cookieName", "cookieValue") // 新建一个cookie
    ck.setMaxAge(24*60*60);  // 设置cookie有效期,单位为秒
    resp.addCookie(ck);	// 添加cookie,响应给客户端
    
  • cookie细节

    • cookie一般保存在客户端本地
    • 一个cookie只能保存一个信息(键值对)
    • 一个web站点可以给浏览器发送多个cookie,最多存放20个cookie
    • cookie大小有限制,限制为4kb
    • 浏览器cookie上限为300个
  • 删除cookie的方式

    • 不设置cookie有效期,关闭浏览器,自动失效
    • 设置maxAge为0

Session

  • session概念

    • 服务器会给每个用户(浏览器)创建一个session对象
    • 一个session对象独占一个浏览器,只要浏览器没有关闭,这个session就存在
    • 用户登录之后,整个网站它都可以以登录状态访问
    • 用途有保存用户信息,保存购物车信息和记录登录状态等
  • 注销session设置

    • 手动注销
      session.invalidate()  // 手动注销session
      
    • web.xml设置
      <session-config>
      	<!--1分钟后session自动失效,以分钟为单位-->
      	<session-timeout>1</session-timeout>
      </session-config>
      
  • session和cookie区别

    • cookie把用户数据写给用户的浏览器,在浏览器中保存(可以保存多个)
    • session把用户数据写到用户独占的session中,在服务端保存(保存重要信息,减少服务器资源浪费)

JSP

  • JSP全称Java Server Pages,即Java服务端页面,用于动态web技术
  • JSP与HTML很相似,它们之间的区别:
    • HTML只能给用户提供静态数据
    • JSP页面中可以嵌入Java代码,为用户提供动态数据

JSP原理

  • JSP文件最终会在Tomcat的work工作目录中变成Java程序
    在这里插入图片描述

  • 并从其变成的Java程序中分析出,JSP最终会被转换成一个继承HttpServlet的Java类,该类实现的功能就是将JSP文件中的内容传输给客户端

  • 所以本质上,浏览器向服务器发送请求,不管访问什么资源,都是在访问Servlet

  • 源码剖析

    • 判断请求方法

      if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
            final java.lang.String _jspx_method = request.getMethod();
            if ("OPTIONS".equals(_jspx_method)) {
              response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
              return;
            }
            if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
              response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
              response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
              return;
            }
          }
      
    • 输出jsp页面前添加的代码,定义一些对象。这些对象都可以在jsp文件中以${}的形式直接使用

      final javax.servlet.jsp.PageContext pageContext;
      javax.servlet.http.HttpSession session = null;
      final javax.servlet.ServletContext application;
      final javax.servlet.ServletConfig config;
      javax.servlet.jsp.JspWriter out = null;
      final java.lang.Object page = this;
      javax.servlet.jsp.JspWriter _jspx_out = null;
      javax.servlet.jsp.PageContext _jspx_page_context = null;
      
    • 最后给上面定义的对象赋值,并输出页面

      response.setContentType("text/html");
      pageContext = _jspxFactory.getPageContext(this, request, response,
        			null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;
      
      out.write("<html>\n");
      out.write("<body>\n");
      out.write("<h2>Hello World!</h2>\n");
      out.write("</body>\n");
      out.write("</html>\n");
      
  • 所以,在JSP页面中只要是Java代码,就是原封不动的输出,如果是html代码,则会被转换为文本通过out.write输出给客户端

  • Java代码以<%%>的形式内嵌

  • 原理流程图

在这里插入图片描述

MVC三层架构模型

  • Model

    • 业务处理:业务逻辑(Service层)
    • 数据持久化:CRUD(Dao层)
  • View

    • 展示数据
    • 给用户提供链接发起Servlet请求
  • Controller(Servlet)

    • 接收用户请求(req:请求参数、session信息等)
    • 交给业务层处理相应业务
    • 控制试图跳转
  • 典型例子

    用户点击登录-->控制层接收用户的登录请求-->控制层处理用户请求(获得用户登录的参数,如账号密码等)-->将参数交给业务层处理登录业务(账号、密码是否正确,还有可能涉及数据库事务处理)-->交给Dao层查询用户名和密码是否正确-->数据库
    

过滤器(Filter)

  • Filter是Servlet的过滤器,主要用于完成一些通用的操作,如编码的过滤判断用户的登录状态、过滤垃圾请求等

  • Filter 被称为过滤器,其主要作用是对 Servlet 容器调用 Servlet 的过程进行拦截,从而在 Servlet 进行响应处理的前后实现一些特殊功能

  • Filter拦截过程图示
    在这里插入图片描述
    当用户通过浏览器访问服务器中的目标资源时,首先会被 Filter 拦截,在 Filter 中进行预处理操作,然后再将请求转发给目标资源。当服务器接收到这个请求后会对其进行响应,在服务器处理响应的过程中,也需要将响应结果经过滤器处理后,才发送给客户端

  • 本质上,Filter 过滤器就是一个实现了 javax.servlet.Filter 接口的类,在 javax.servlet.Filter 接口中定义了三个方法

    方法声明方法描述
    init(FilterConfig filterConfig)init() 方法用于初始化过滤器,开发人员可以在 init() 方法中完成与构造方法类似的初始化功能,如果初始化代码中要使用到 FillerConfig 对象,那么,这些初始化代码就只能在 Filler 的 init() 方法中编写,而不能在构造方法中编写在 Web 应用程序加载时会被调用,只被调用一次
    doFilter(ServletRequest request,SeivletResponse response, FilterChain chain)doFilter() 方法有多个参数,其中,参数 request 和 response 为 Web 服务器或 Filter 链中的上一个 Filter 传递过来的请求和响应对象;参数 chain 代表当前 Filter 链的对象,只有在当前 Filter 对象中的 doFilter() 方法内部需要调用 FilterChain 对象的 doFilter() 方法,才能把请求交付给 Filter 链中的下一个 Filter 或者目标程序处理会被调用多次只要客户端有请求时就会被调用),Filter 所有的工作集中在 doFilter() 方法中
    destroy()destroy() 方法在 Web 服务器卸载 Filter 对象之前被调用,该方法用于释放被 Filter 对象打开的资源,例如关闭数据库和 I/O 流在 Web 应用程序卸载(或关闭)时被调用,只被调用一次

过滤器映射方式

  • 在web.xml配置文件中,使用Filter 的\ <filter-mapping> 元素用于配置过滤器拦截的资源信息,如果想让过滤器拦截所有的请求,那么可以使用通配符*实现
    <filter>
        <filter-name>FilterName</filter-name>
        <filter-class>com.demo.filter.FilterName</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>FilterName</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
  • 拦截不同方式的访问请求
    • 在 web.xml 文件中,每一个 <filter-mapping> 元素都可以配置一个 Filter 所负责拦截的资源。在\ <filter-mapping> 元素中有一个特殊的子元素 <dispatcher>,该元素用于指定过滤器所拦截的资源被 Servlet 容器调用的方式。<dispatcher> 元素的值共有四个
      在这里插入图片描述
    • 以FORWARD为例,xml配置如下
      <filter>
          <filter-name>ForwardFilter</filter-name>
          <filter-class>com.demo.filter.ForwardFilter</filter-class>
      </filter>
      <filter-mapping>
          <filter-name>ForwardFilter</filter-name>
          <url-pattern>/first.jsp</url-pattern>
          <dispatcher>FORWARD</dispatcher>
      </filter-mapping>
      
      该过滤器会拦截所有以请求转发(forward)的方式访问/first.jsp的所有请求

过滤器链

  • 在一个 Web 应用程序中可以注册多个 Filter 程序,每个 Filter 程序都可以针对某一个 URL 进行拦截。如果多个 Filter 程序都对同一个 URL 进行拦截,那么这些 Filter 就会组成一个Filter 链
  • Filter 链用 FilterChain 对象表示,FilterChain 对象中有一个 doFilter() 方法,该方法的作用是让 Filter 链上的当前过滤器放行,使请求进入下一个 Filter
  • 因为Filter的拦截作用,可以使用Filter进行权限访问控制,对某些访问没有权限的页面的请求进行拦截,不调用doFilter方法传递给下一个Filter,而将其重定向到权限不足的出错页面
  • 拦截过程如下图
    在这里插入图片描述
  • 当浏览器访问 Web 服务器中的资源时,需要经过两个过滤器 Filter1 和 Filter2。首先 Filter1 会对这个请求进行拦截,在 Filter1 中处理完请求后,通过调用 Filter1 的 doFilter() 方法将请求传递给 Filter2,Filter2 处理用户请求后同样调用 doFilter() 方法,最终将请求发送给目标资源。当 Web 服务器对这个请求做出响应时,也会被过滤器拦截,但这个拦截顺序与之前相反,最终将响应结果发送给客户端浏览器
  • 需要注意的是,Filter 链中各个 Filter 的拦截顺序与它们在 web.xml 文件中 <filter-mapping> 元素的映射顺序一致

编码过滤器示例

  • 编写编码过滤器类
    package com.demo.filter;
    
    import javax.servlet.*;
    import java.io.IOException;
    
    public class CharacterEncodingFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            Filter.super.init(filterConfig);
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
    
            request.setCharacterEncoding("utf-8");
            response.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");
    
            chain.doFilter(request, response);  // 过滤器有多个,传递给下一个过滤器,不执行传递则被拦截
        }
    
        @Override
        public void destroy() {
            Filter.super.destroy();
        }
    }
    
  • web.xml配置filter,与servlet配置一致
    <filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>com.demo.filter.CharacterEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <!--要执行过滤的访问指定url路径的所有请求-->
    <url-pattern>/servlet/*</url-pattern>
    </filter-mapping>
    

Servlet事件监听器

  • Servlet 事件监听器是一个实现了特定接口的 Java 程序,这个程序专门用于监听 Web 应用中 ServletContext、HttpSession 和 ServletRequest 等域对象的创建和销毁过程、监听这些域对象属性的修改以及感知绑定到 HttpSession 域中的某个对象的状态

  • Servlet 规范中定义了八种监听器,这八种监听器的类型及作用如下表所示
    在这里插入图片描述

  • 根据监听事件的不同,可以将表中的监听器分为如下三类

    • 用于监听域对象创建和销毁的事件监听器(ServletContextListener 接口、HttpSessionListener 接口、ServletRequestListener 接口)
    • 用于监听域对象属性增加和删除的事件监听器(ServletContextAttributeListener 接口、HttpSessionAttributeListener 接口、ServletRequestAttributeListener 接口)
    • 用于监听绑定到 HttpSession 域中某个对象状态的事件监听器(HttpSessionBindingListener 接口、HttpSessionActivationListener 接口)
  • 在 Servlet 规范中,这三类事件监听器都定义了相应的接口,在编写事件监听器程序时只需实现对应的接口即可。在使用监听程序时,Web 服务器会根据监听器所实现的接口,把它注册到被监听的对象上,当触发了某个对象的监听事件时,Web 容器将会调用 Servlet 监听器与之相关的方法对事件进行处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值