如何在 Spring Boot 中拦截 HTTP 请求响应

举报
千锋教育 发表于 2023/08/14 16:52:25 2023/08/14
【摘要】 Spring 中的拦截器用于在控制器处理客户端请求或响应之前或将响应发送回客户端之前拦截客户端请求或响应。拦截器是 Spring Web MVC 框架的一部分,提供了一种向应用程序的请求响应生命周期添加预处理/后处理逻辑的方法。拦截器的实时用例拦截器的一些常见用例包括任务,例如:日志记录: 拦截器可用于记录 HTTP 请求和响应。这对于调试或跟踪应用程序的性能很有用。安全性: 拦截器可用于执...

Spring 中的拦截器用于在控制器处理客户端请求或响应之前或将响应发送回客户端之前拦截客户端请求或响应。

拦截器是 Spring Web MVC 框架的一部分,提供了一种向应用程序的请求响应生命周期添加预处理/后处理逻辑的方法。

拦截器的实时用例

拦截器的一些常见用例包括任务,例如:

  • 日志记录: 拦截器可用于记录 HTTP 请求和响应。这对于调试或跟踪应用程序的性能很有用。
  • 安全性: 拦截器可用于执行安全策略。例如,拦截器可用于在允许用户访问资源之前检查用户是否经过身份验证。
  • 缓存: 拦截器可用于缓存 HTTP 请求和响应。这可以通过减少需要向底层资源发出请求的次数来提高应用程序的性能。
  • 转换: 拦截器可用于转换 HTTP 请求和响应。例如,拦截器可用于将 JSON 请求转换为 XML 响应。

Spring 请求生命周期

在典型的 Spring Boot 应用程序流程中,当客户端向特定端点(URL)发送 HTTP 请求时,该请求首先由 Web 服务器(例如 Apache Tomcat 或 Jetty)接收,然后转发到 Spring Boot 应用程序。

DispatcherServlet 是 Spring Boot 应用程序中传入请求的入口点。一旦 DispatcherServlet 收到请求,它就会查询 HandlerMapping。

HandlerMapping 负责根据控制器中定义的 URL 映射来确定哪个控制器应该处理传入请求。

Spring Boot 中的拦截器

在 Spring Boot 中创建拦截器

要在 Spring Boot 中创建拦截器,通常需要创建一个实现该HandlerInterceptor接口的类。

HandlerInterceptor接口共有三个方法:

  1. preHandle():preHandle()方法是HandlerInterceptor中最重要的方法。该方法在调用实际控制器方法之前执行。它返回一个布尔值,指示请求是否应该继续发送到控制器或停止。

  2. postHandle():该方法在调用控制器方法之后但在将响应发送到客户端之前执行。它允许您在渲染响应之前修改模型和视图。您可以使用此方法执行处理请求后需要执行的任何任务。例如,您可以使用该postHandle()方法向响应添加附加信息,或记录响应。

  3. afterCompletion():该方法在响应发送到客户端后执行。即使在处理请求期间抛出异常,也会调用此方法。它对于清理或资源释放任务很有用。

检查基本身份验证的拦截器

现在让我们创建一个拦截器来执行基本的身份验证检查。仅针对特定端点调用此拦截器/products/new。在允许访问控制器之前,它将执行基本的身份验证检查。

对于此示例,我们将硬编码用户名和密码来验证用户传递的凭据。

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

@Slf4j
public class BasicAuthInterceptor implements HandlerInterceptor {
    private static final String USERNAME = "admin";
    private static final String PASSWORD = "admin";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("BasicAuthInterceptor::preHandle()");

        String authHeader = request.getHeader("Authorization");
        if (authHeader != null && authHeader.startsWith("Basic ")) {

            String base64Credentials = authHeader.substring("Basic ".length());
            byte[] decodedCredentials = Base64.getDecoder().decode(base64Credentials);
            String credentials = new String(decodedCredentials, StandardCharsets.UTF_8);

            String[] parts = credentials.split(":");
            String username = parts[0];
            String password = parts[1];

            if (USERNAME.equals(username) && PASSWORD.equals(password)) {
                return true;
            }
        }

        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("BasicAuthInterceptor::postHandle()");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("BasicAuthInterceptor::afterCompletion()");
    }
}

在 Spring Boot 中注册拦截器

创建自定义拦截器后,您需要使用WebMvcConfigurer配置将其注册到 Spring Boot 应用程序:

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 WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new BasicAuthInterceptor())
                .addPathPatterns("/products/new");
    }
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。