你是否遇到过service层需要request请求对象呢 ? --当然笔者认为这样的编码习惯是不好的编码习惯。
当然本文的重点不是讨论编码习惯的问题。
不多说了,直接上代码吧
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
这样我们就可以在任何地方获取到 HttpServletRequest , HttpServletResponse 对象。
那我们就有一个问题了 。
为什么会达到这样的一个效果呢 ?
那么我们就来分析一下源码,去看一下这样的效果是怎么实现的.
我们先来看一下 RequestContextHolder 对象
看到这里我们就应该明白 其实这就是通过本地线程 (ThreadLocal)去实现的。
我们再来RequestContextHolder#getRequestAttributes 方法。
这里我们发现是 先从 requestAttributesHolder 中获取,当获取不到,就再次从 inheritableRequestAttributesHolder 中获取。
那么问题来了 ,我们是什么时候放进去的呢 ?
那么怎么办呢? debug一下就知道了
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 对象放到本地线程中
相关推荐
在Spring MVC框架中,RequestContextHolder是一个非常实用的工具类,它允许我们在Service层以及其它非Controller层获取到当前HTTP请求的相关信息,如HttpServletRequest对象、HttpServletResponse对象等。...
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { double waitTime = limiter.acquire(); // 尝试获取令牌,返回等待时间 if (waitTime...
- 可以直接在处理器方法中声明`HttpServletRequest`、`HttpServletResponse`、`HttpSession`等Servlet API参数,以直接访问请求、响应和会话对象。但需要注意,由于控制器是单例的,直接注入`ServletContext`可能...
例如,HttpServletRequest和HttpServletResponse这两个Servlet API的核心对象,经常作为参数直接出现在Spring MVC的接口方法中,这意味着Spring MVC的设计是基于Servlet容器的。这与Struts2的事件驱动模型不同,后者...
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String url = request.getRequestURI(); String method = request.getMethod(); if ...
- **请求与响应处理**:学习HttpServletRequest和HttpServletResponse对象的使用,处理客户端的请求和向客户端发送响应。 - **会话管理**:了解session的创建、使用和销毁,以及如何设置和获取session属性。 5. *...
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { filterChain.doFilter(request, response); ...
在服务器开发部分,会讲解HTTP协议、Servlet、HttpServletRequest和HttpServletResponse,以及Cookie和Session的管理。 【Web开发与项目实践】 课程还包括JSP动态网页开发、文件上传下载、MVC架构、Filter过滤器和...
编写一个`SpringMvcHandler`,它实现了`ChannelInboundHandlerAdapter`,并将Netty接收到的HTTP请求转化为Spring MVC的`HttpServletRequest`和`HttpServletResponse`对象,然后调用相应的Controller方法。...
- **请求和响应处理**:使用 HttpServletRequest 和 HttpServletResponse 处理客户端请求和响应。 #### 框架 - **Spring**:一款轻量级的 IoC 和 AOP 框架。 - **SpringMVC**:基于 Spring 的 MVC 框架。 - **...
本例中微信方法并没有设置参数,实际可以灵活设置参数,例如我们可以在方法中设置HttpServletRequest request,HttpServletResponse response,InMessage in, WeixinContext context等参数,这部分内容也放在使用...
11. **请求范围共享**:ServletContext,HttpServletRequest,HttpServletResponse。 12. **文件上传与进度条**:Servlet,FileItem,FileUpload。 13. **Ajax封装**:JavaScript面向对象编程。 14. **JQuery访问...
然而,需要注意的是,由于Spring MVC的Controller默认为单例模式,直接在类字段中存储`HttpServletRequest`、`HttpServletResponse`和`ModelMap`可能会引发线程安全问题。文章作者已经意识到这个问题,并采用了`...
此外,如果需要对不同URL或特定请求进行不同的日志处理,可以利用`HandlerMapping`中的`HandlerMapping.getHandler(HttpServletRequest request)`方法获取到处理当前请求的处理器对象,进一步判断是否需要进行日志...
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 此处省略了具体的用户登录验证逻辑 if (!isUserLoggedIn(request)) { // 用户未...