`
wx1569484809
  • 浏览: 63677 次
文章分类
社区版块
存档分类
最新评论

springmvc 从本地线程获取HttpServletRequest , HttpServletResponse 对象

 
阅读更多

你是否遇到过service层需要request请求对象呢 ? --当然笔者认为这样的编码习惯是不好的编码习惯。

当然本文的重点不是讨论编码习惯的问题。

不多说了,直接上代码吧 

HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();

这样我们就可以在任何地方获取到 HttpServletRequest  , HttpServletResponse 对象。

那我们就有一个问题了 。

为什么会达到这样的一个效果呢 ?

那么我们就来分析一下源码,去看一下这样的效果是怎么实现的.

我们先来看一下 RequestContextHolder 对象

111342_OCPH_2848251.png

看到这里我们就应该明白  其实这就是通过本地线程 (ThreadLocal)去实现的。

我们再来RequestContextHolder#getRequestAttributes 方法。

111610_Iw3u_2848251.png

这里我们发现是 先从 requestAttributesHolder 中获取,当获取不到,就再次从 inheritableRequestAttributesHolder 中获取。

那么问题来了 ,我们是什么时候放进去的呢 ?

那么怎么办呢? debug一下就知道了 

112113_AOMM_2848251.png

1 , 我们看一下我们怎么set 进本地线程中就知道了 

2 , 我们发现FrameworkServlet 中的 initContextHolders 中设置的 ,看到这样的方法名,我们就应该知道我们找对地方了。

3 ,我们看到 FrameworkServlet 中的 processRequest 方法中调用 initContextHolders 。那我们来分析一下 processRequest方法吧

protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
long startTime = System.currentTimeMillis();
Throwable failureCause = null;
//获取上一个请求保存的LocaleContext
    LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
//建立新的LocaleContext
    LocaleContext localeContext = buildLocaleContext(request);
//获取上一个请求保存的RequestAttributes
    RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();
//建立新的RequestAttributes
    ServletRequestAttributes requestAttributes = buildRequestAttributes(request, 
response, previousAttributes);
    WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), 
new RequestBindingInterceptor());
//具体设置的方法  *****   主要在这个方法里面设置
    initContextHolders(request, localeContext, requestAttributes);
try {
        doService(request, response);
    }catch (ServletException ex) {
        failureCause = ex;
         throw ex;
    }catch (IOException ex) {
       failureCause = ex;
       throw ex;
    }catch (Throwable ex) {
        failureCause = ex;
        throw new NestedServletException("Request processing failed", ex);
    }finally {
         //恢复  , 在这边清空了 本地线程里面的 请求对象等
        resetContextHolders(request, previousLocaleContext, previousAttributes);

        if (requestAttributes != null) {
           requestAttributes.requestCompleted();
        }
      // ... 省略部分代码
      //发布事件
        publishRequestHandledEvent(request, response, startTime, failureCause);
    }
}

 

由此可见 :

springmvc 帮助我们做了很多的事 ,把 request ,reponse 对象放到本地线程中

转载于:https://my.oschina.net/haitaoxiedekongjian/blog/1563701

分享到:
评论

相关推荐

    SpringMVC中RequestContextHolder获取请求信息的方法

    在Spring MVC框架中,RequestContextHolder是一个非常实用的工具类,它允许我们在Service层以及其它非Controller层获取到当前HTTP请求的相关信息,如HttpServletRequest对象、HttpServletResponse对象等。...

    SpringMVC 限流的示例代码

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { double waitTime = limiter.acquire(); // 尝试获取令牌,返回等待时间 if (waitTime...

    SpringMVC——处理器方法参数的处理.docx

    - 可以直接在处理器方法中声明`HttpServletRequest`、`HttpServletResponse`、`HttpSession`等Servlet API参数,以直接访问请求、响应和会话对象。但需要注意,由于控制器是单例的,直接注入`ServletContext`可能...

    SpringMVC源码剖析(四)- DispatcherServlet请求转发的实现1

    例如,HttpServletRequest和HttpServletResponse这两个Servlet API的核心对象,经常作为参数直接出现在Spring MVC的接口方法中,这意味着Spring MVC的设计是基于Servlet容器的。这与Struts2的事件驱动模型不同,后者...

    springMVC中基于token防止表单重复提交方法

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String url = request.getRequestURI(); String method = request.getMethod(); if ...

    软件程序员考试题目(java为主)

    - **请求与响应处理**:学习HttpServletRequest和HttpServletResponse对象的使用,处理客户端的请求和向客户端发送响应。 - **会话管理**:了解session的创建、使用和销毁,以及如何设置和获取session属性。 5. *...

    在Spring MVC或Spring Boot中使用Filter打印请求参数问题

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { filterChain.doFilter(request, response); ...

    王道训练营Java工程师 课程大纲1

    在服务器开发部分,会讲解HTTP协议、Servlet、HttpServletRequest和HttpServletResponse,以及Cookie和Session的管理。 【Web开发与项目实践】 课程还包括JSP动态网页开发、文件上传下载、MVC架构、Filter过滤器和...

    spring mvc中启动netty

    编写一个`SpringMvcHandler`,它实现了`ChannelInboundHandlerAdapter`,并将Netty接收到的HTTP请求转化为Spring MVC的`HttpServletRequest`和`HttpServletResponse`对象,然后调用相应的Controller方法。...

    java大纲资料.txt

    - **请求和响应处理**:使用 HttpServletRequest 和 HttpServletResponse 处理客户端请求和响应。 #### 框架 - **Spring**:一款轻量级的 IoC 和 AOP 框架。 - **SpringMVC**:基于 Spring 的 MVC 框架。 - **...

    java微信公众号MVC开发框架

    本例中微信方法并没有设置参数,实际可以灵活设置参数,例如我们可以在方法中设置HttpServletRequest request,HttpServletResponse response,InMessage in, WeixinContext context等参数,这部分内容也放在使用...

    java技术点

    11. **请求范围共享**:ServletContext,HttpServletRequest,HttpServletResponse。 12. **文件上传与进度条**:Servlet,FileItem,FileUpload。 13. **Ajax封装**:JavaScript面向对象编程。 14. **JQuery访问...

    spring mvc中注解@ModelAttribute的妙用分享

    然而,需要注意的是,由于Spring MVC的Controller默认为单例模式,直接在类字段中存储`HttpServletRequest`、`HttpServletResponse`和`ModelMap`可能会引发线程安全问题。文章作者已经意识到这个问题,并采用了`...

    使用spring拦截器实现日志管理实例

    此外,如果需要对不同URL或特定请求进行不同的日志处理,可以利用`HandlerMapping`中的`HandlerMapping.getHandler(HttpServletRequest request)`方法获取到处理当前请求的处理器对象,进一步判断是否需要进行日志...

    Spring MVC拦截器的基本使用方法

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 此处省略了具体的用户登录验证逻辑 if (!isUserLoggedIn(request)) { // 用户未...

Global site tag (gtag.js) - Google Analytics