当前位置: 首页 > news >正文

Spring 框架:过滤器 vs 调度器 Servlet vs 拦截器 vs 控制器

什么是过滤器?

如上图所示,过滤器是 Web 服务器的 Servlet 容器的一部分。它不属于任何框架,如 Struts 或 Spring。过滤器用于处理请求,甚至可以在请求到达 Servlet 之前将其阻塞。它还可以对响应进行操作,并在到达客户端之前对其进行修改

Spring Security 使用过滤器进行身份验证和授权。Spring Security 可以拦截所有传入和传出的流量,因此 Spring Security 可以在 Spring MVC 框架之外使用。

以下是我们可以使用 servlet 过滤器执行的任务列表:

  • 服务器端日志记录。
  • 将请求参数记录到日志文件。
  • 审计
  • 服务器端身份验证和授权。
  • 压缩和解压。
  • 加密和解密。
  • 服务器端验证。

Spring MVC 和 Dispatcher Servlet

Spring MVC 是基于模型-视图-控制器 (MVC) 设计模式 的最流行的 Java Web 框架。Spring MVC 的核心元素是 Dispatcher Servlet,它是处理所有请求的前端控制器,并为 Spring 框架内的所有请求提供入口点。它负责将传入的 HTTP 请求定向到应用程序的所有其他处理程序和控制器。它与 Spring IOC 容器完全集成,支持 Spring 的所有特性。

在 Spring Boot 出现之前,Dispatcher Servlet 是在 web.xml 文件中声明的,如下:

<web-app>
   <servlet>
         <servlet-name>example</servlet-name> 
        <servlet <b>class</b>> 
             org.springframework.web.servlet.DispatcherServlet 
        </servlet-<b>class</b>> 
        <load-on-startup>1</load -on-startup> 
    </servlet>
   <servlet-mapping>
        <servlet-name>test</servlet-name> 
        <url-pattern>*.test</url-pattern> 
   </servlet-mapping>
 </web-app>

这个DispatcherServlet是实际的Servlet,它继HttpServlet承自基类。 Spring Boot 为Spring MVC 提供了开箱即用的支持,而无需为 Dispatcher Servlet 定义任何配置。

Spring Boot 提供了spring-boot-starter-web库,用于使用 Spring MVC 开发 Web 应用程序。自动配置是 Spring Boot 的重要特性之一,使用它,Spring Boot会自动注册和配置 DispatcherServlet 。因此,我们不需要在 web.xml 文件中手动注册DispatcherServlet

默认情况下,spring-boot-starter-web starter 将DispatcherServlet配置为 URL 模式“/”。

但是,如果需要,我们可以使用server.servlet 自定义 URL 模式。

* application.properties文件中如下:

server.servlet.context-path=/hello spring.mvc.servlet.path=/world

通过上面的配置,DispatcherServlet被配置为处理 URL 模式/world并且根上下文路径将是/hello。因此,DispatcherServlet监听http://localhost: 8080 /hello/world

什么是处理程序拦截器?

HandlerInterceptor是 Spring MVC 框架 的一部分,它们位于 DispatcherServlet 和控制器之间。它们用于在到达控制器之前或呈现视图之前和之后拦截请求。

例如,我们可以使用拦截器在向控制器发送请求之前添加请求头,并在向客户端发送响应之前添加响应头。

处理程序拦截器减少重复并允许更细粒度的功能,例如:

  • 处理横切关注点,例如应用程序日志记录
  • 详细的授权检查
  • 操作 Spring 上下文或模型

Spring 拦截器是一个扩展HandlerInterceptorAdapter类或实现HandlerInterceptor接口的类。

HandlerInterceptor包含三个主要方法:

  • prehandle() — 在实际处理程序执行之前调用
  • postHandle() — 在处理程序执行后调用
  • afterCompletion() — 在完成请求并生成视图后调用

如上图所示,在调用控制器之前调用了 preHandle 方法。控制器类执行完毕后,执行 postHandle 方法。一旦视图被渲染,请求和响应都准备好了,然后执行 afterCompletion 方法。

什么是控制器?

在 Spring Boot 中,控制器类负责处理传入的 REST API 请求、准备模型以及返回要呈现为响应的视图。Spring 中的控制器类由@Controller 或@RestController 注释进行注释。

控制器

@Controller 用于将类标记为 Spring MVC 控制器。@Controller注释是通用构造型注释的特化@Component。使用 Controller 注解可以将类识别为 Spring 管理的组件。我们可以使用 Controller 在 Spring MVC 中返回一个视图。

如果我们使用 Controller,我们可以有返回视图的处理程序以及返回 JSON 响应到 API 的处理程序。在这种情况下,我们需要在每个需要返回 JSON 响应的处理程序方法上使用 @ResponseBody

在下面的示例中,我们使用了Controller注释并使用了 2 个处理程序方法。第一个方法返回一个名为 hello.jsp 或 hello.html 的视图,而第二个方法是一个 Rest API,它以 JSON 的形式返回员工对象。这是因为将对象转换为 JSON 响应的ResponseBody注释:

@Controller
@RequestMapping(<font>"employees"</font><font>)
<b>public</b> <b>class</b> MVCController {
@GetMapping(</font><font>"/hello"</font><font>)
<b>public</b> String hello(Locale locale, Model model) {
        Date date = <b>new</b> Date();
        model.addAttribute(</font><font>"serverTime"</font><font>, formattedDate);
        <b>return</b> </font><font>"hello"</font><font>;
}
@GetMapping(value = </font><font>"/{name}"</font><font>)
@ResponseBody
<b>public</b> Employee getEmployeeByName(@PathVariable String name) {
  <b>return</b> employee;
}
}
</font>

因此,使用 Controller 注释,我们可以将它用作返回 View 的 MVC 控制器,也可以通过在 Handler Methods 上使用 ResponseBody 来使用它。

Rest控制器

如今,大多数应用程序都使用由前端框架(如 Angular/React JS 等)使用的 Rest API,这些框架期望 JSON 响应,这与期望呈现 JSP 页面的旧应用程序不同。因此,我们现在主要使用 Rest Controller,而不是使用 MVC Controller。

RestController 用于在 @RestController 注释 的帮助下制作宁静的 Web 服务。此注解用于类级别,并允许类处理客户端发出的请求。

RestController 允许您处理所有 REST API ,例如 GET、POST、Delete 和 PUT 请求。

@RestController = @Controller + @ResponseBody

在下面的示例中,我们看到使用了 RestController 而不是 Controller 注释。我们不需要为处理程序方法指定 ResponseBody,因为它已经在 RestController 注释中实现。

@RestController
@RequestMapping(<font>"employees"</font><font>)
<b>public</b> <b>class</b> MVCController {
@GetMapping(value = </font><font>"/{name}"</font><font>)
<b>public</b> Employee getEmployeeByName(@PathVariable String name) {
  <b>return</b> employee;
}
}
</font>

因此,如果我们希望我们的控制器只处理 Rest API,那么我们可以使用 RestController 注解。

总结

在本文中,我们详细了解了 Filter、Dispatcher Servlet、Handler Interceptor 和 Controller。过滤器是 Servlet Container 的一部分,而其他三个组件是 Spring Framework 的一部分。本文的重要内容是这些组件的执行顺序。过滤器首先被执行,然后是 Dispatcher Servlet、Handler Interceptor,最后是 Controller。

相关文章:

  • Java项目源码SSM校园网报修系统
  • NET面试--C#基础
  • 浙大MPA网上报名关键信息点提醒,选错一个,回头重来
  • 消除笔去水印怎么做?教你怎么用这些消除笔软件
  • JAVAFile类以及怎么在目录不存在的情况下创建文件
  • 解决SQL映射文件的警告提示
  • 对比base64图片使用base256加密解密前后的区别
  • python面经(滴滴、理想、momenta)
  • 2022年五一杯数学建模B题矿石加工质量控制问题解题全过程及论文和程序
  • 向移动端发展会是Web3的突破契机吗?
  • 网课答案公众号怎样可以快速调用查题功能
  • 03-JVM-对象内存、执行引擎
  • 本地缓存组件
  • 掌握这25个单行代码技巧,你也能写出『高端』Python代码
  • 看过来,这里教你如何更好地呈现荣誉证书
  • @angular/forms 源码解析之双向绑定
  • Asm.js的简单介绍
  • canvas 五子棋游戏
  • Fundebug计费标准解释:事件数是如何定义的?
  • iOS帅气加载动画、通知视图、红包助手、引导页、导航栏、朋友圈、小游戏等效果源码...
  • TCP拥塞控制
  • TypeScript实现数据结构(一)栈,队列,链表
  • Vue官网教程学习过程中值得记录的一些事情
  • Webpack 4 学习01(基础配置)
  • 今年的LC3大会没了?
  • 聚簇索引和非聚簇索引
  • 如何借助 NoSQL 提高 JPA 应用性能
  • 实现菜单下拉伸展折叠效果demo
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 一道面试题引发的“血案”
  • 一个JAVA程序员成长之路分享
  • #Js篇:单线程模式同步任务异步任务任务队列事件循环setTimeout() setInterval()
  • (1)Android开发优化---------UI优化
  • (十三)Flask之特殊装饰器详解
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • (原創) 物件導向與老子思想 (OO)
  • (转)大道至简,职场上做人做事做管理
  • (转载)在C#用WM_COPYDATA消息来实现两个进程之间传递数据
  • .NET Core工程编译事件$(TargetDir)变量为空引发的思考
  • .NET DevOps 接入指南 | 1. GitLab 安装
  • .NET 应用架构指导 V2 学习笔记(一) 软件架构的关键原则
  • .net6Api后台+uniapp导出Excel
  • .net访问oracle数据库性能问题
  • .net流程开发平台的一些难点(1)
  • /etc/shadow字段详解
  • :“Failed to access IIS metabase”解决方法
  • [ 数据结构 - C++]红黑树RBTree
  • [100天算法】-不同路径 III(day 73)
  • [ArcPy百科]第三节: Geometry信息中的空间参考解析
  • [BZOJ1010] [HNOI2008] 玩具装箱toy (斜率优化)
  • [C++基础]-初识模板
  • [IE9] 解决了傲游、搜狗浏览器在IE9下网页截图的问题
  • [leetcode]Clone Graph
  • [LOJ#6259]「CodePlus 2017 12 月赛」白金元首与独舞
  • [LWC] Components Communication