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

Spring Boot框架中在Controller方法里获取Request和Response对象的2种方式

写在前面

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.FrameworkServletprotected final void processRequest(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 省略其他代码...// 在工具类RequestContextHolder中注入ServletRequest和ServletResponse对象initContextHolders(request, localeContext, requestAttributes);// 省略其他代码...
}

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

http://www.zskr.cn/news/70362.html

相关文章:

  • 第五天项目
  • 团队作业4——7天敏捷冲刺
  • 【小题狂练A】“一切沉溺者挣扎者向所谓极致献出 最稚嫩的人格”
  • 第三天项目
  • 第7篇Scrum冲刺博客
  • 一些md5绕过总结(长期补充)
  • C语言随堂笔记-1
  • 第3篇Scrum冲刺博客
  • Pytorch基础学习和实战,基于b站小土堆视频笔记 - 教程
  • 炫彩活体检测:金融科技的“生命感知”安全锁
  • 团队作业四——项目冲刺
  • excel选中整列,设置单元格自动换行,为什么粘贴内容后还不换行,单独设置该单元格自动换行就可以,为什么整列设置没效果
  • 实用指南:GitHub 全方位指南(续):实战进阶与生态拓展​
  • Day6 Scrum 冲刺日志
  • Day3 Scrum 冲刺日志
  • Day2 Scrum 冲刺日志
  • 第4篇:Alpha阶段Day4冲刺日志
  • 短连接和长连接
  • 上海素食餐厅十大推荐:探寻舌尖上的清净之味
  • 2025年自动称重包装机生产厂排名:看看哪家合作案例多值得选
  • 上海私藏餐厅指南:从素食雅宴到小众珍味,解锁高品质用餐体验
  • 2025年上海特色素食店盘点:这5家高格调餐厅值得一访
  • 2025年寻味慢生活:上海适合休闲放松的特色素食店推荐
  • 2025年上海健康饮食餐厅精选:兼顾美味与营养的用餐指南
  • 深入解析:MME:多模态大语言模型综合评估基准
  • 上海商铺装修哪家好?2025 全业态适配与优质服务商指南
  • 2025配件包装机老牌厂家TOP5权威推荐:资深厂商甄选指南
  • 基于整数MCU的FOC电机控制深度解析:从浮点到定点的工程实践 - 实践
  • 2025年12月京东e卡兑换,高口碑回收平台:实测费率与安全交易解析!
  • 助听器验配中心推荐哪家好?2025年4大甄选维度+5家优质机构测评,避坑指南