优雅处理HTTP请求:过滤器、拦截器、ControllerAdvice和自定义AOP

我们在开发Spring Boot应用程序时,经常会遇到需要对HTTP请求进行一些处理的情况,例如鉴权、数据校验、请求日志记录等等。在处理HTTP请求时,我们可以使用四种不同的技术来实现这些功能:过滤器、拦截器、ControllerAdvice和自定义AOP。

在本文中,我们将分别介绍这四种技术的概念、用法和区别,并举例说明如何在Spring Boot应用程序中使用它们来实现对HTTP请求的统一处理。

基本概念及拦截执行顺序

  1. 过滤器(Filter):过滤器是Java Web中的一种技术,它在请求到达Servlet之前或之后进行处理。因此,过滤器是最先执行的拦截器。在过滤器中可以进行一些通用的业务处理,例如鉴权、数据校验、请求日志记录等等。Spring Boot应用程序中注册的过滤器按照注册的顺序依次执行。
  2. 拦截器(Interceptor):拦截器是Spring MVC框架提供的一种技术,它在请求到达Controller之前或之后进行处理。因此,拦截器在过滤器之后执行,但在请求到达Controller之前。在拦截器中可以进行请求的修改或者一些通用的业务逻辑处理。Spring Boot应用程序中注册的拦截器按照注册的顺序依次执行。
  3. ControllerAdvice:ControllerAdvice是Spring MVC提供的一个注解,用于定义一个全局的异常处理器、数据绑定器和模型处理器。它可以被用于处理所有的Controller中抛出的异常和响应,对于多个Controller中重复的异常处理可以进行统一管理。ControllerAdvice在请求到达Controller之后执行,可以对Controller返回的数据进行统一处理,例如添加通用的响应头、设置统一的返回值格式等等。
  4. 自定义AOP(Aspect-Oriented Programming):自定义AOP是一种编程范式,它可以用于在方法调用前、后或抛出异常时添加一些横切逻辑。在Spring Boot应用程序中,自定义AOP切面可以用于对HTTP请求进行统一处理,例如获取和解析请求头信息、请求日志记录、鉴权等等。自定义AOP切面的执行顺序在拦截器之后,在请求到达Controller之前执行。

总的来说,四种拦截方式的执行顺序是过滤器->拦截器->ControllerAdvice->自定义AOP。

但是需要注意的是,这并不是绝对的顺序,具体的执行顺序还会受到过滤器链、拦截器链、AOP切入位置等因素的影响,例如

  • 如果在过滤器或拦截器中调用了chain.doFilter(request, response)或handlerInterceptor.preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)方法,则会依次调用过滤器链和拦截器链的下一个过滤器或拦截器。
  • 自定义AOP的执行顺序在ControllerAdvice之后,是因为一般情况下我们会将切入点选在Controller的方法上

四种拦截方法的使用case

过滤器

在Spring Boot项目中,可以使用过滤器(Filter)来统一处理HTTP请求,并获取和解析请求头中的内容。过滤器可以在请求到达Servlet之前或之后进行一些处理操作。

以下例子展示如何在Spring Boot项目中实现一个过滤器来获取和解析请求头中的内容:

  1. 创建一个过滤器类,实现Filter接口。在该过滤器类中,可以重写doFilter方法,在该方法中获取并解析请求头信息。
 

Java

复制代码

public class MyFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; // 获取请求头信息 String headerInfo = httpRequest.getHeader("Header-Info"); // 解析请求头信息 // ... chain.doFilter(request, response); // 继续执行请求处理 } // 可以重写init和destroy方法进行初始化和销毁操作 }

  1. 在Spring Boot应用程序中注册该过滤器类。可以通过创建一个配置类并继承WebMvcConfigurerAdapter类,然后重写addFilters方法来注册过滤器。
 

Java

复制代码

public class MyFilterConfig extends WebMvcConfigurerAdapter { @Bean public FilterRegistrationBean<MyFilter> myFilter() { FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new MyFilter()); registrationBean.addUrlPatterns("/*"); // 指定过滤的URL return registrationBean; } }

这样,当请求到达时,就会先进入过滤器的doFilter方法进行处理,并获取和解析请求头信息。过滤器可以处理任何类型的请求,而不仅仅是Web请求,因此需要在过滤器中进行类型判断。

拦截器

在Spring Boot项目中,可以使用拦截器(Interceptor)来对HTTP请求进行统一转换和处理请求头信息。拦截器可以在请求处理前和处理后进行一些处理操作。

以下例子展示如何在Spring Boot项目中实现一个拦截器来获取和解析请求头中的信息:

创建一个拦截器类,实现HandlerInterceptor接口。在该拦截器类中,可以重写preHandle方法,在该方法中获取并解析请求头信息。

 

Java

复制代码

public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 获取请求头信息 String headerInfo = request.getHeader("Header-Info"); // 解析请求头信息 // ... return true; // 返回true继续执行请求处理,返回false则不执行请求处理 } // 可以重写 afterCompletion 和 postHandle 方法进行请求处理后的操作 }

在Spring Boot应用程序中注册该拦截器类。可以通过创建一个配置类并继承WebMvcConfigurerAdapter类,然后重写addInterceptors方法来注册拦截器。

 

Java

复制代码

@Configuration public class MyInterceptorConfig extends WebMvcConfigurerAdapter { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyInterceptor()); } }

这样,当请求到达时,就会先进入拦截器的preHandle方法进行处理,并获取和解析请求头信息。注意,拦截器只能处理@Controller注解或@RequestMapping注解的处理器方法,并且只对Web请求有效,对于非Web请求(如静态资源)不会进行拦截。

除preHandle(目标方法执行前执行), HandlerInterceptor还有两外两个方法:

  • postHandle 目标方法执行后执行
  • afterCompletion 请求完成时执行

ControllerAdvice

  • @ControllerAdvice是Spring MVC提供的一个注解,用于定义一个全局的异常处理器、数据绑定器和模型处理器。它可以被用于处理所有的Controller中抛出的异常和响应,对于多个Controller中重复的异常处理可以进行统一管理。
  • @ControllerAdvice注解对于应用程序中所有的@Controller注解的类中的方法进行全局处理,可以捕获Controller中的异常并返回相应的响应信息,也可以在Controller中返回数据之前对数据进行统一处理。
  • @ControllerAdvice注解所标注的类中,可以定义多个方法,每个方法可以处理不同的异常或返回不同类型的数据。在方法上可以使用@ExceptionHandler、@InitBinder或@ModelAttribute注解来指定要处理的异常类型、数据绑定规则和模型处理规则。

下面是一个@ControllerAdvice注解的示例:

 

Java

复制代码

@ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) @ResponseBody public ResponseEntity<String> handleException(Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage()); } }

上面的代码定义了一个全局异常处理器,用于处理所有Controller中抛出的Exception异常,如果出现异常则返回一个HTTP 500错误响应,并将异常信息作为响应体返回。

另外,@ControllerAdvice注解中还可以添加basePackages属性或value属性来指定需要处理的Controller所在的包路径或类。例如:

 

Java

复制代码

@ControllerAdvice(basePackages = "com.example.controller") public class GlobalExceptionHandler { // ... }

这样就只会处理com.example.controller包下的Controller中抛出的异常。

总之,@ControllerAdvice是一个很有用的注解,可以让我们在应用程序中统一处理异常和响应,避免重复的代码,提高代码的可维护性和可读性。

自定义AOP

在Spring Boot项目中,可以使用自定义AOP的方式来统一处理HTTP请求,并获取和解析请求头中的内容。通过自定义AOP切面,可以在请求处理前和处理后添加相应的切面逻辑。

以下例子展示如何在Spring Boot项目中实现自定义AOP切面来获取和解析请求头中的内容:

创建一个注解,用于标注需要进行切面处理的方法。在该注解中添加一个String类型的属性,用于指定需要获取的请求头信息。

 

Java

复制代码

@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MyAnnotation { String value(); }

创建一个切面类,实现Aspect接口,并在该类中定义一个切点方法和一个通知方法。在切点方法中,使用@Pointcut注解来指定需要进行切面处理的方法;在通知方法中,通过JoinPoint参数获取请求对象,并从请求对象中获取并解析请求头信息。

 

Java

复制代码

@Aspect @Component public class MyAspect { @Pointcut("@annotation(com.example.demo.MyAnnotation)") public void myPointcut() {} @Around("myPointcut()") public Object myAdvice(ProceedingJoinPoint joinPoint) throws Throwable { // 获取请求对象 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); // 获取注解中指定的请求头信息 MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); MyAnnotation annotation = methodSignature.getMethod().getAnnotation(MyAnnotation.class); String headerInfo = request.getHeader(annotation.value()); // 解析请求头信息 // ... // 继续执行请求处理 Object result = joinPoint.proceed(); // 处理请求处理结果 // ... return result; } }

在需要进行切面处理的方法上添加自定义注解,并指定需要获取的请求头信息。

 

Java

复制代码

@RestController public class MyController { @MyAnnotation("Header-Info") @GetMapping("/hello") public String hello() { return "Hello World!"; } }

这样,在请求到达需要进行切面处理的方法时,就会先进入自定义AOP切面的通知方法进行处理,并获取和解析请求头信息。注意,自定义AOP切面可以处理任何类型的方法,而不仅仅是@Controller注解或@RequestMapping注解的处理器方法,它也可以处理非Web请求(如异步方法或定时任务等)。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整全套资源下载地址:https://download.csdn.net/download/qq_27595745/70761177 【完整课程列表】 完整版Java web开发教程PPT课件 Java开发进阶教程 第01章 JavaScript简介以及基本语法(共15页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第02章 Dom模型,控制客户端元素(共15页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第03章 表单验证,常用函数(共15页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第04章 自定义web服务器(共14页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第06章 SERVLET(共15页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第07章 JSP语法及运行过程(共13页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第08章 JSP内置对象(共22页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第09章 jstl、el、java bean(共18页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第10章 过滤器、监听器、自定义标签(共19页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第11章 AJAX实现(共11页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第12章 自定义mvc框架(共11页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第13章 spring ioc aop(共18页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第14章 spring mvc介绍,原理以及搭建(共15页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第15章 spring mvc核心对象拦截器(共26页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第17章 自定义orm框架(共11页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第18章 mybatis框架的搭建以及应用(共13页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第19章 mybatis高级应用(共21页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第20章 数据库连接池,缓存(共15页).pptx 完整版Java web开发教程PPT课件 Java开发进阶教程 第22章 常用框架的介绍以及环境搭建(共16页).pptx JS课程案例ebookHTML\网上书店需求文档.doc

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值