3

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

 1 year ago
source link: https://www.jdon.com/62583
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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


什么是过滤器?

v2-9afb32bd0aa912cc7af6573e40a9b3ec_720w.jpg?source=d16d100b


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

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

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

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

Spring MVC 和 Dispatcher Servlet

v2-106dcd67c575da9ba0ac27ce9de87231_720w.jpg?source=d16d100b



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 class> 
             org.springframework.web.servlet.DispatcherServlet 
        </servlet-class> 
        <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() — 在完成请求并生成视图后调用
v2-686b3524a34444ca977cfb0bd16348dd_720w.jpg?source=d16d100b



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

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

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

v2-da490d50d6a43ec476234e17f7755cea_720w.jpg?source=d16d100b



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

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

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

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

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

v2-9933ab8e8379bac8e55e33ed1e82f659_720w.jpg?source=d16d100b



RestController 用于在@RestController 注释的帮助下制作宁静的 Web 服务。此注解用于类级别,并允许类处理客户端发出的请求。
RestController 允许您处理所有REST API,例如 GET、POST、Delete 和 PUT 请求。

@RestController = @Controller + @ResponseBody

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

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

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

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK