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

黄岛网站建设多少钱/西安seo搜推宝

黄岛网站建设多少钱,西安seo搜推宝,web应用开发用什么语言,网站设计怎么做明信片文章目录 SpringBoot 过滤器 vs 拦截器过滤器 (Filter)定义特点使用场景实现步骤创建过滤器类注册过滤器(可选,如果不使用 WebFilter 注解) 拦截器 (Interceptor)定义特点使用场景实现步骤创建拦截器类注册拦截器 过滤器与拦截器的比较实际项…

文章目录

  • SpringBoot 过滤器 vs 拦截器
    • 过滤器 (Filter)
      • 定义
      • 特点
      • 使用场景
      • 实现步骤
        • 创建过滤器类
        • 注册过滤器(可选,如果不使用 @WebFilter 注解)
    • 拦截器 (Interceptor)
      • 定义
      • 特点
      • 使用场景
      • 实现步骤
        • 创建拦截器类
        • 注册拦截器
      • 过滤器与拦截器的比较
      • 实际项目中的选择
      • 结论

SpringBoot 过滤器 vs 拦截器

在构建Spring Boot应用程序时,开发者经常需要在过滤器(Filters)与拦截器(Interceptors)之间做出选择,尽管两者都能在请求-响应周期中发挥作用,但它们各自有着特定的设计目的和应用场景。下面我们将探讨过滤器与拦截器之间的主要区别,并给出在不同情况下如何合理选用的指导原则。

过滤器 (Filter)

定义

过滤器是Java Servlet API的一部分,用于在请求达到目标资源(如Servlet或JSP页面)之前或在响应从目标资源返回到客户端之后进行预处理或后处理。它们可以被看作是请求和响应的“管道”,允许开发人员执行一些跨切割关注点的操作,如编码转换、添加响应头、身份验证、日志记录等。

特点

  • 生命周期管理:过滤器具有初始化(init),过滤(doFilter)和销毁(destroy)的方法,这些方法分别在过滤器创建、每次请求和服务器关闭时调用。
  • 执行顺序:过滤器的执行顺序是由部署描述符(web.xml)或等效的Java配置类中定义的过滤器映射所决定的。
  • 跨容器:过滤器可以在任何实现了Servlet规范的容器中工作,这意味着它们可以用于任何基于Servlet的Web应用程序,而不仅仅是Spring Boot应用。
  • 请求/响应处理:过滤器可以在请求到达目标资源前和响应离开容器后执行操作,这使得它们非常适合处理一些需要在所有请求中都生效的任务。

使用场景

  • 安全性:实现身份验证和授权逻辑,确保只有经过验证的用户才能访问某些资源。
  • 编码转换:在请求和响应中进行字符集转换,以支持国际化。
  • 日志记录:记录每个请求的信息,用于调试和监控应用程序行为。
  • 性能监控:测量请求处理时间,以便进行性能分析和优化。
  • 资源限制:限制请求频率,防止资源滥用,例如通过实现速率限制功能。
  • 响应头添加:自动添加HTTP响应头,如CORS支持或安全相关的头部信息。

实现步骤

在Spring Boot项目中,过滤器可以通过实现javax.servlet.Filter接口或使用Spring的org.springframework.web.filter.OncePerRequestFilter来创建,然后在WebSecurityConfigurerAdapter中配置,或者直接在SpringBootServletInitializer中注册,以确保它们在应用程序启动时正确加载和初始化。

创建过滤器类

实现 javax.servlet.Filter 接口。

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// 初始化代码,可选实现System.out.println("Filter initialized");}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {// 过滤器逻辑在请求处理前执行System.out.println("Request received at filter");// 继续调用过滤器链,传递请求和响应chain.doFilter(request, response);// 过滤器逻辑在响应处理后执行System.out.println("Response leaving filter");}@Overridepublic void destroy() {// 销毁代码,可选实现System.out.println("Filter destroyed");}
}
注册过滤器(可选,如果不使用 @WebFilter 注解)
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class FilterConfig {@Beanpublic FilterRegistrationBean<MyFilter> loggingFilter(){FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean<>();// 注册自定义过滤器实例registrationBean.setFilter(new MyFilter());// 指定过滤器应用的 URL 模式registrationBean.addUrlPatterns("/*");// 设置过滤器优先级,值越低优先级越高registrationBean.setOrder(1);return registrationBean;}
}

拦截器 (Interceptor)

定义

拦截器是AOP(面向切面编程)概念在Web开发中的具体应用,主要用于在不修改原始代码的情况下增强程序的功能。在Spring Boot框架中,拦截器被广泛应用于处理请求的特定阶段,如在请求到达控制器之前或之后执行某些操作。它提供了一种机制,可以在请求处理的不同阶段执行自定义的代码逻辑。

特点

  • 生命周期钩子:拦截器提供了多个钩子方法,如preHandle()postHandle()afterCompletion(),分别在请求处理的开始、结束和完成后调用。
  • 动态性:可以通过配置来决定哪些请求会被拦截器处理,而无需修改具体的控制器代码。
  • 非侵入性:拦截器的设计使得业务逻辑与横切关注点分离,使得代码更加模块化和可维护。
  • 可插拔性:可以根据需要轻松地添加、移除或更改拦截器,而不会影响到现有的业务逻辑。

使用场景

  • 权限认证与授权:在请求到达控制器之前检查用户的身份和权限,以确定是否允许访问相应的资源。
  • 日志记录:记录请求和响应的详细信息,有助于调试和性能分析。
  • 数据预处理:在请求数据到达控制器前进行预处理,如数据转换、校验等。
  • 响应修饰:在响应发送给客户端前,可以对响应体进行修改或补充,如添加额外的响应头。
  • 性能监控:测量控制器方法的执行时间,监控应用性能。
  • 事务管理:在业务逻辑方法执行前后进行事务管理,确保数据的一致性和安全性。

实现步骤

在Spring Boot中,拦截器的实现和注册相对简单。开发者可以创建一个实现了HandlerInterceptor接口的类,并在配置类中使用@ConfigurationWebMvcConfigurer接口来注册拦截器。这样,拦截器就能按照定义的规则自动生效,无需手动在每个控制器上添加注解或配置。这种机制使得Spring Boot应用程序能够高效地处理各种请求,并能轻松地扩展其功能,而不会破坏原有的代码结构。

创建拦截器类

实现 HandlerInterceptor 接口。

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 请求处理前逻辑System.out.println("Request intercepted at preHandle");// 返回 true 继续请求,返回 false 中断请求return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {// 请求处理后逻辑System.out.println("Request intercepted at postHandle");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 请求处理完成后的逻辑System.out.println("Request intercepted at afterCompletion");}
}
注册拦截器
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class InterceptorConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 注册自定义拦截器实例,并指定拦截的路径模式registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/login", "/register"); // 可以排除某些路径不被拦截}
}

过滤器与拦截器的比较

特性过滤器 (Filter)拦截器 (Interceptor)
所属规范Servlet 规范Spring MVC 框架
作用范围整个应用程序的所有请求仅限于 Spring MVC 的控制器请求
修改请求响应可以直接修改请求和响应通常不直接修改请求和响应
配置方式通过 @WebFilter 注解或 FilterRegistrationBean通过实现 HandlerInterceptor 并注册
典型应用场景认证、日志、压缩响应日志、权限校验、视图处理

在实际项目中选择使用过滤器(Filter)还是拦截器(Interceptor),主要取决于你的具体需求和它们各自的特点。以下是一些指导原则,帮助你做出明智的选择:

实际项目中的选择

过滤器(Filter)

  • 何时使用

    • 当你需要在所有请求的入口处执行代码,而不论请求最终会到达哪个具体的Spring组件时。
    • 当你关注的是跨多个应用程序的通用功能,如安全性(如CSRF保护)、编码转换、性能监控、添加响应头等。
    • 当你想要在请求到达Spring MVC DispatcherServlet之前或在响应被发送给客户端之后执行代码。
  • 优势

    • 过滤器在Servlet容器级别运行,这意味着它们适用于所有基于Servlet的Web应用,而不局限于Spring MVC或Spring Boot。
    • 过滤器的执行顺序在web.xml或等效的Java配置中明确定义,这提供了清晰的控制流。

拦截器(Interceptor)

  • 何时使用

    • 当你需要在Spring MVC的请求处理链中添加逻辑,尤其是在请求到达控制器方法前后或在视图渲染前后。
    • 当你关心的是与Spring MVC紧密相关的功能,如用户认证、权限检查、日志记录、数据预处理等。
    • 当你需要访问Spring MVC的上下文,如模型数据、视图、控制器等。
  • 优势

    • 拦截器是Spring框架的一部分,可以充分利用Spring的特性,如依赖注入、事务管理等。
    • 拦截器的配置更加灵活,你可以选择只对特定的请求路径应用拦截器。

实际考虑因素

  • 性能影响:考虑过滤器和拦截器对系统性能的影响。通常,过滤器由于更早地介入请求流程,可能对性能有更大影响。
  • 代码耦合度:拦截器更倾向于业务逻辑的紧密集成,而过滤器则更偏向于独立于具体业务逻辑的跨切关注点。
  • 维护成本:评估长期维护成本,包括代码的可读性、可测试性和可扩展性。

结论

在SpringBoot应用中,过滤器和拦截器都扮演着重要角色,选择使用哪一种应基于项目需求和它们各自的特点进行权衡。如果需求指向处理所有请求的低层次功能,如编码转换或安全检查,过滤器可能是更优的选择;而如果功能更偏向于Spring MVC的高层次操作,如权限控制或数据预处理,拦截器则更为适合。在实际项目中,我们可能会发现同时利用过滤器和拦截器的情况,以便全面覆盖应用程序的不同方面。记住,没有一成不变的规则,最重要的是根据项目的具体需求和上下文来灵活决定使用哪种机制,以达到最佳的效果。

相关文章:

【过滤器 vs 拦截器】SpringBoot中过滤器与拦截器:明智选择的艺术(如何在项目中做出明智选择)

文章目录 SpringBoot 过滤器 vs 拦截器过滤器 (Filter)定义特点使用场景实现步骤创建过滤器类注册过滤器&#xff08;可选&#xff0c;如果不使用 WebFilter 注解&#xff09; 拦截器 (Interceptor)定义特点使用场景实现步骤创建拦截器类注册拦截器 过滤器与拦截器的比较实际项…...

2024-06学习笔记

1.事务与数据库链接的占用 如果用Transactional注解&#xff0c;那在第一次与数据库交互的时候&#xff0c;就会打开数据库链接&#xff0c;再整个方法执行完&#xff0c;才会关闭数据库链接。 即使后边用的事务传播是required_new,那之前的事务也是被挂起&#xff0c;不会被…...

【VUE】封装一个追随鼠标的漂浮组件框架

红色箭头代表鼠标位置&#xff0c;蓝色区域跟随鼠标出现&#xff0c;鼠标进行其他操作的时候&#xff0c;蓝色区域隐藏。 vue全码 <template><divmousemove"updatePosition"mouseleave"hideDiv"class"container":style"{ positi…...

mapstruct与lombok结合使用

问题 如果同时使用mapstruct与lombok&#xff0c;需要多添加一个lombok支持mapstruct的依赖库。 解决 <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId> </dependency><dependency><groupId&…...

【SpringBoot】Web开发之URL映射

RequestMapping("/getDataById/{id}") public String getDataById(PathVariable("id") Long id){ return "getDataById:"id; }46 如果URL中的参数名称与方法中的参数名称一致&#xff0c;则可以简化为&#xff1a; RequestMapping("/get…...

对递归的一些理解。力扣206题:翻转链表

今天在刷力扣的时候&#xff0c;在写一道翻转链表的题目的过程中&#xff0c;在尝试使用递归解决该问题的时候&#xff0c;第一版代码却每次都返回的是null&#xff0c;这个错误让我尝试去debug了一下&#xff0c;最终找出了问题&#xff0c;并且让我对递归有了一些更深的理解&…...

Kafka面试三道题

针对Kafka的面试题&#xff0c;从简单到困难&#xff0c;我可以给出以下三道题目&#xff1a; 1. Kafka的基本概念与优势 问题&#xff1a;请简要介绍Kafka是什么&#xff0c;并说明它相比传统消息队列的优势有哪些&#xff1f; 答案&#xff1a; Kafka定义&#xff1a;Apa…...

C/C++编程-算法学习-数字滤波器

数字滤波器 一阶低通滤波器结论推导11. 基本公式推导2. 截止频率 和 采样频率 推导 实现 二阶低通滤波器实现1实现2 一阶低通滤波器 结论 其基本原理基于以下公式&#xff1a; o u t p u t [ n ] α ∗ i n p u t [ n ] ( 1 − α ) ∗ o u t p u t [ n − 1 ] output[n] …...

maven介绍 搭建Nexus3(maven私服搭建)

Maven是一个强大的项目管理工具&#xff0c;它基于项目对象模型&#xff08;POM&#xff1a;Project Object Model&#xff09;的概念&#xff0c;通过XML格式的配置文件&#xff08;pom.xml&#xff09;来管理项目的构建 Maven确实可以被视为一种工程管理工具或项目自动化构…...

电商项目之如何判断线程池是否执行完所有任务

文章目录 1 问题背景2 前言3 4种常用的方法4 代码4.1 isTerminated()4.2 线程池的任务总数是否等于已执行的任务数4.3 CountDownLatch计数器4.4 CyclicBarrier计数器 1 问题背景 真实生产环境的电商项目&#xff0c;常使用线程池应用于执行大批量操作达到高性能的效果。应用场景…...

【前端 15】Vue生命周期

Vue生命周期 在Vue.js中&#xff0c;了解组件的生命周期对于开发者来说是至关重要的。Vue的生命周期指的是Vue实例从创建到销毁的一系列过程&#xff0c;每个阶段都对应着特定的生命周期钩子&#xff08;或称为生命周期方法&#xff09;&#xff0c;允许我们在不同的时间点加入…...

PCIe总线-Linux内核PCIe软件框架分析(十一)

1.简介 Linux内核PCIe软件框架如下图所示&#xff0c;按照PCIe的模式&#xff0c;可分为RC和EP软件框架。RC的软件框架分为五层&#xff0c;第一层为RC Controller Driver&#xff0c;和RC Controller硬件直接交互&#xff0c;不同的RC Controller&#xff0c;其驱动实现也不相…...

视觉SLAM第二讲

SLAM分为定位和建图两个问题。 定位问题 定位问题是通过传感器观测数据直接或间接求解位置和姿态。 通常可以分为两类&#xff1a;基于已知地图的定位和基于未知地图的定位。 基于已知地图的定位 利用预先构建的地图&#xff0c;结合传感器数据进行全局定位。SLAM中的全局…...

mysql1055报错解决方法

目录 一、mysql版本 二、 问题描述 三、解决方法 1.方法一&#xff08;临时&#xff09; 2.方法二&#xff08;永久&#xff09; 一、mysql版本 mysql版本&#xff1a;5.7.23 二、 问题描述 在查询时使用group by语句&#xff0c;出现错误代码&#xff1a;1055&#xf…...

Java的@DateTimeFormat注解与@JsonFormat注解的使用对比

Java的DateTimeFormat注解与JsonFormat注解的使用对比 在Java开发中&#xff0c;处理日期和时间格式时&#xff0c;我们经常会使用到DateTimeFormat和JsonFormat注解。这两个注解主要用于格式化日期和时间&#xff0c;但在使用场景和功能上有所不同。本文将详细介绍这两个注解…...

德国云手机:企业移动办公解决方案

在现代商业环境中&#xff0c;移动办公已经成为一种趋势。德国云手机作为一种高效的解决方案&#xff0c;为企业提供了强大的支持。本文将探讨德国云手机如何优化企业的移动办公环境。 一、德国云手机的主要优势 高灵活性 德国云手机具有高度的灵活性&#xff0c;能够根据用户需…...

【React】useState:状态管理的基石

文章目录 一、什么是 useState&#xff1f;二、useState 的基本用法三、useState 的工作原理四、高级用法五、最佳实践 在现代前端开发中&#xff0c;React 是一个非常流行的库&#xff0c;而 useState 是 React 中最重要的 Hook 之一。useState 使得函数组件能够拥有自己的状态…...

商品中心关于缓存热key的解决方案

缓存热key一旦被击穿&#xff0c;流量势必会打到数据库&#xff0c;如果数据库崩了&#xff0c;游戏直接结束。 从两点来讨论&#xff1a;如何监控、如何解决。 如何监控 通过业务评估&#xff1a;比如营销活动推出的商品或者热卖的商品。基于LRU的命令&#xff0c;redis-cl…...

【Python系列】Parquet 数据处理与合并:高效数据操作实践

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

大脑自组织神经网络通俗讲解

大脑自组织神经网络的核心概念 大脑自组织神经网络&#xff0c;是指大脑中的神经元通过自组织的方式形成复杂的网络结构&#xff0c;从而实现信息的处理和存储。这一过程涉及到神经元的生长、连接和重塑&#xff0c;是大脑学习和记忆的基础。其核心公式涉及神经网络的权重更新…...

org.springframework.context.annotation.DeferredImportSelector如何使用?

DeferredImportSelector 是 Spring 框架中一个比较高级的功能&#xff0c;主要用于在 Spring 应用上下文的配置阶段延迟导入某些组件或配置。这个功能特别有用&#xff0c;比如在处理依赖于其他自动配置的场景&#xff0c;或者当你想基于某些条件来决定是否导入特定的配置类时。…...

缓慢变化维

缓慢变化维 缓慢变化维&#xff08;Slowly Changing Dimensions&#xff0c;简称SCD&#xff09;是数据仓库中的一个重要概念&#xff0c;用于处理维度表中数据随时间发生的变化。以下是一个具体的例子来描述缓慢变化维&#xff1a; 假设我们有一个销售数据仓库&#xff0c;其…...

Vue常用的指令都有哪些?都有什么作用?什么是自定义指令?

常用指令&#xff1a; 1、v-model 多用于表单元素实现双向数据绑定 (同angular中的ng-model) 2、v-for格式&#xff1a; v-for"字段名in(of)数组json"循环数组或json(同angular中的ng repeat),需要注意从vue2开始取消了$index 3、v-show 4、v-hide 隐藏内容 (同a…...

kettle从入门到精通 第八十一课 ETL之kettle kettle中的json对象字段写入postgresql中的json字段正确姿势

1、上一节可讲解了如何将json数据写入pg数据库表中的json字段&#xff0c;虽然实现了效果&#xff0c;但若客户继续使用表输出步骤则仍然无法解决问题。 正确的的解决方式是设置数据库连接参数stringtypeunspecified 2、stringtypeunspecified 参数的作用&#xff1a; 当设置…...

计算机网络实验-RIP配置与分析

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 一、相关知识 路由信息协议&#xff08;Routing Information Protocol&#xff0c;RIP&#xff09;是一种基于距离向量&#xff08;Distance-Vector&…...

33.【C语言】实践扫雷游戏

预备知识&#xff1a; 第13篇 一维数组 第13.5篇 二维数组 第28篇 库函数 第29篇 自定义函数 第30篇 函数补充 0x1游戏的运行&#xff1a; 1.随机布置雷 2.排雷 基本规则&#xff1a; 点开一个格子后&#xff0c;显示1&#xff0c;对于9*9&#xff0c;代表以1为中心的去…...

git学习笔记(总结了常见命令与学习中遇到的问题和解决方法)

前言 最近学习完git&#xff0c;学习过程中也遇到了很多问题&#xff0c;这里给大家写一篇总结性的博客&#xff0c;主要大概讲述git命令和部分难点问题&#xff08;简单的知识点这里就不再重复讲解了&#xff09; 一.git概述 1.1什么是git Git是一个分布式的版本控制软件。…...

【计算机网络】TCP协议详解

欢迎来到 破晓的历程的 博客 ⛺️不负时光&#xff0c;不负己✈️ 文章目录 1、引言2、udp和tcp协议的异同3、tcp服务器3.1、接口认识3.2、服务器设计 4、tcp客户端4.1、客户端设计4.2、说明 5、再研Tcp服务端5.1、多进程版5.2、多线程版 5、守护进程化5.1、什么是守护进程5.2…...

2.3 大模型硬件基础:AI芯片(上篇) —— 《带你自学大语言模型》系列

本系列目录 《带你自学大语言模型》系列部分目录及计划&#xff0c;完整版目录见&#xff1a;带你自学大语言模型系列 —— 前言 第一部分 走进大语言模型&#xff08;科普向&#xff09; 第一章 走进大语言模型 1.1 从图灵机到GPT&#xff0c;人工智能经历了什么&#xff1…...

Java | Leetcode Java题解之第279题完全平方数

题目&#xff1a; 题解&#xff1a; class Solution {public int numSquares(int n) {if (isPerfectSquare(n)) {return 1;}if (checkAnswer4(n)) {return 4;}for (int i 1; i * i < n; i) {int j n - i * i;if (isPerfectSquare(j)) {return 2;}}return 3;}// 判断是否为…...