惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Know Your Adversary
Know Your Adversary
博客园 - 叶小钗
量子位
大猫的无限游戏
大猫的无限游戏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 【当耐特】
博客园 - Franky
有赞技术团队
有赞技术团队
博客园 - 聂微东
腾讯CDC
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Jina AI
Jina AI
Last Week in AI
Last Week in AI
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Cloudbric
Cloudbric
WordPress大学
WordPress大学
W
WeLiveSecurity
V2EX - 技术
V2EX - 技术
博客园_首页
S
Security @ Cisco Blogs
The Last Watchdog
The Last Watchdog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Security Latest
Security Latest
L
Lohrmann on Cybersecurity
T
Threat Research - Cisco Blogs
Forbes - Security
Forbes - Security
宝玉的分享
宝玉的分享
The Register - Security
The Register - Security
The Hacker News
The Hacker News
B
Blog RSS Feed
C
CXSECURITY Database RSS Feed - CXSecurity.com
Schneier on Security
Schneier on Security
T
Troy Hunt's Blog
The GitHub Blog
The GitHub Blog
Hacker News: Ask HN
Hacker News: Ask HN
Spread Privacy
Spread Privacy
Hugging Face - Blog
Hugging Face - Blog
博客园 - 三生石上(FineUI控件)
GbyAI
GbyAI
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
罗磊的独立博客
Blog — PlanetScale
Blog — PlanetScale
M
MIT News - Artificial intelligence
T
Tor Project blog
S
Security Affairs
Security Archives - TechRepublic
Security Archives - TechRepublic
NISL@THU
NISL@THU
P
Proofpoint News Feed
C
Cyber Attacks, Cyber Crime and Cyber Security

博客园 - nuccch

在Cursor中读取飞书文档 使用GIMP去除水印的有效方法 如何基于VSCode打造Java开发环境 在IDEA中配置注释模板 在Windows中使用Linux系统 树形层级结构的数据库表设计方案 如何理解和认识设计模式 申请Let's Encrypt免费HTTPS证书的方法 为GIT仓库项目设置独立配置参数 DBeaver设置不断开连接 构建工具Gradle入门实践 如何在Maven中排除依赖传递 87键键盘的数字键对应快捷键含义 关于Java JSON库的选择 解决mybatis批量更新慢问题 解决Spring Cloud Gateway中使用CompletableFuture.supplyAsync()执行Feign调用报错 解读Spring Boot框架中不同位置抛出异常的处理流程 探究Spring Boot框架中访问不存在的接口时触发对error路径的访问 Spring Cloud工程中使用Nacos配置中心的2种方式 Swagger开启账号验证访问
Spring Boot框架中在Controller方法里获取Request和Response对象的2种方式
nuccch · 2025-12-03 · via 博客园 - nuccch

写在前面

javax.servlet.ServletRequestjavax.servlet.ServletResponse都是Servlet容器中定义的接口,分别用于获取客户端请求信息和将响应消息发送给客户端。
有两种方法在Contoller方法中获取它们:

  1. 直接在Controller方法参数中声明
  2. 通过工具类org.springframework.web.context.request.RequestContextHolder获取

实际的对象实例类跟具体的Servlet容器有关:

  • 如果Servlet容器为Tomcat,javax.servlet.ServletRequest实现类为org.apache.catalina.connector.RequestFacadejavax.servlet.ServletResponse实现类为org.apache.catalina.connector.ResponseFacade
  • 如果Servlet容器为Undertow,javax.servlet.ServletRequest实现类为io.undertow.servlet.spec.HttpServletRequestImpljavax.servlet.ServletResponse实现类为io.undertow.servlet.spec.HttpServletResponseImpl

在Controller方法参数中声明

可以直接在Controller方法参数中声明javax.servlet.ServletRequestjavax.servlet.ServletResponse对象,如下示例:

@GetMapping("/hello")
public String request(HttpServletRequest req, HttpServletResponse resp) {
    System.out.println("req: " + req);
    System.out.println("resp: " + resp);
    return "Success";
}

之所以能直接在Controller方法参数中声明javax.servlet.ServletRequestjavax.servlet.ServletResponse对象,实际上是在org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues()方法中进行了解析处理,如下:

// org.springframework.web.method.support.InvocableHandlerMethod
private Object[] getMethodArgumentValues(NativeWebRequest request, ModelAndViewContainer mavContainer,
        Object... providedArgs) throws Exception {

    MethodParameter[] parameters = getMethodParameters();
    Object[] args = new Object[parameters.length];
    for (int i = 0; i < parameters.length; i++) {
        MethodParameter parameter = parameters[i];
        parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
        args[i] = resolveProvidedArgument(parameter, providedArgs);
        if (args[i] != null) {
            continue;
        }
        if (this.argumentResolvers.supportsParameter(parameter)) { // 判断是否为支持解析的参数类型
            try {
                args[i] = this.argumentResolvers.resolveArgument( // 解析参数对象
                        parameter, mavContainer, request, this.dataBinderFactory);
                continue;
            }
            catch (Exception ex) {
                if (logger.isDebugEnabled()) {
                    logger.debug(getArgumentResolutionErrorMessage("Failed to resolve", i), ex);
                }
                throw ex;
            }
        }
        if (args[i] == null) {
            throw new IllegalStateException("Could not resolve method parameter at index " +
                    parameter.getParameterIndex() + " in " + parameter.getMethod().toGenericString() +
                    ": " + getArgumentResolutionErrorMessage("No suitable resolver for", i));
        }
    }
    return args;
}

最终通过org.springframework.web.servlet.mvc.method.annotation.ServletRequestMethodArgumentResolver.resolveArgument()方法解析获取到具体对象。

通过RequestContextHolder工具类获取

在使用Spring Boot框架时,除了可以直接在Controller方法参数中声明javax.servlet.ServletRequestjavax.servlet.ServletResponse对象,还可以通过工具类org.springframework.web.context.request.RequestContextHolder获取,如下示例:

@GetMapping("/hello")
public String hello() {
    RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
    if (requestAttributes != null && requestAttributes instanceof ServletRequestAttributes) {
        ServletRequestAttributes httpRequestAttributes = (ServletRequestAttributes) requestAttributes;
        HttpServletRequest req = httpRequestAttributes.getRequest();
        HttpServletResponse resp = httpRequestAttributes.getResponse();
        System.out.println("req: " + req);
        System.out.println("resp: " + resp);
    }
    return "Success";
}

之所以可以通过RequestContextHolder工具类获取javax.servlet.ServletRequestjavax.servlet.ServletResponse对象,是因为在org.springframework.web.servlet.FrameworkServlet.processRequest()方法中进行了注入。

// org.springframework.web.servlet.FrameworkServlet

protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    // 省略其他代码...

    // 在工具类RequestContextHolder中注入ServletRequest和ServletResponse对象
    initContextHolders(request, localeContext, requestAttributes);

    // 省略其他代码...
}

【参考】
Spring——Web作用域:RequestContextListener
springboot 整合 ServletRequestListener监听器