由SpringMVC中RequetContextListener说起

零、引言

RequetContextListener从名字结尾Listener来看就知道属于监听器。

所谓监听器就是监听某种动作,在其开始(初始化)和结束(销毁)的时候进行某些操作。

由此可以猜测:该类用于在RequetContext(请求上下文对象)创建和销毁的时候进行某些操作(哪些操作?结尾总结!)

一、web.xml配置

要使用该listener对象需要在web.xml中进行如下配置。

<!-- 此监听器是监听HttpRequest对象,方便ContextHolderUtils程序调用HttpRequest对象 -->
<listener>
<description>request监听器</description>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

二、三个重要类解读

2.1 RequetContextListener

public class RequestContextListener implements ServletRequestListener {
    private static final String REQUEST_ATTRIBUTES_ATTRIBUTE =
            RequestContextListener.class.getName() + ".REQUEST_ATTRIBUTES";
    // 在请求进入的时候,初始化变量放入ThreadLocal<T>中
    @Override
    public void requestInitialized(ServletRequestEvent requestEvent) {
        //判定当前的requetEvent中获取的ServletRequest()对象是否是HttpServletRequet对象
        if (!(requestEvent.getServletRequest() instanceof HttpServletRequest)) {
            throw new IllegalArgumentException(
                    "Request is not an HttpServletRequest: " + requestEvent.getServletRequest());
        }
        //强制转型为 HttpServletRequest
        HttpServletRequest request = (HttpServletRequest) requestEvent.getServletRequest();
        // ServletRequestAttributes 保存了HttpServletRequet、Response、Session等变量
        ServletRequestAttributes attributes = new ServletRequestAttributes(request);
        request.setAttribute(REQUEST_ATTRIBUTES_ATTRIBUTE, attributes);
        LocaleContextHolder.setLocale(request.getLocale());
        //RequestContextHolder里面有一个ThreadLocal,当前线程共享
        RequestContextHolder.setRequestAttributes(attributes);
    }
    //在请求被销毁的时候,将在初始化时候的ThreadLocal变量清空。
    @Override
    public void requestDestroyed(ServletRequestEvent requestEvent) {
        ...
    }
}

2.2 RequetContextHolder

public abstract class RequestContextHolder  {
    //ThreadLocal<T>变量用于保存当前线程的共享变量
    private static final ThreadLocal<RequestAttributes> requestAttributesHolder =
            new NamedThreadLocal<RequestAttributes>("Request attributes");
    private static final ThreadLocal<RequestAttributes> inheritableRequestAttributesHolder =
            new NamedInheritableThreadLocal<RequestAttributes>("Request context");
    /**
     * 将线程中的共享变量清除掉,会在RequetContextListner的destory()方法中调用。
     */
    public static void resetRequestAttributes() {
        //清空变量
        requestAttributesHolder.remove();
        inheritableRequestAttributesHolder.remove();
    }
    //过渡方法
    public static void setRequestAttributes(RequestAttributes attributes) {
        setRequestAttributes(attributes, false);
    }
    // 核心的方式:将RequetAttrubutes(Request/Response/Session)放入到ThreadLocal<T>中进行共享
    public static void setRequestAttributes(RequestAttributes attributes, boolean inheritable) {
        if (attributes == null) {
            resetRequestAttributes();
        }
        else {
            if (inheritable) {
                inheritableRequestAttributesHolder.set(attributes);
                requestAttributesHolder.remove();
            }
            else {
                requestAttributesHolder.set(attributes);
                inheritableRequestAttributesHolder.remove();
            }
        }
    }

2.3 ServletRequestAttributes

public class ServletRequestAttributes extends AbstractRequestAttributes {
    private final HttpServletRequest request;
    private HttpServletResponse response;
    private volatile HttpSession session;
    private final Map<String, Object> sessionAttributesToUpdate = new ConcurrentHashMap<String, Object>(1);
}

三、使用方法

从以上可以知道RuquetAttribute是放在了ThreadLocal中,则在该次请求中,可以在任意的代码位置中获取该该对象,由此拿到HttpServletRequet等对象。

HttpServletRequest request =((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();

利用该方法可以在任意位置获取request对象.

四、总结

RequetContextListner主要作用就一个:

将本次请求的 ServletRequestAttributes 对象 保存在ThreadLocal中,方便在某一次请求的任意代码位置获取(包括直接在service层获取)。

http://www.cnblogs.com/LiuChunfu/p/7067828.html

时间: 2024-07-28 16:02:23

由SpringMVC中RequetContextListener说起的相关文章

SpringMVC中文件上传的客户端验证

SpringMVC中文件上传的客户端验证 客户端验证主要思想:在jsp页面中利用javascript进行对文件的判断,完成验证后允许上传 验证步骤:1.文件名称 2.获取文件的后缀名称 3.判断哪些文件类型允许上传 4.判断文件大小 5.满足条件后跳转后台实现上传 前台界面(验证上传文件是否格式满足要求): <body> <h2>文件上传</h2> <form action="upload01" method="post" 

springmvc 中 Instantiation of bean failed实例化Bean失败错误

配置springMVC 项目时,启动tomcat服务器报错: 错误: 信息: Initializing Spring FrameworkServlet 'springmvc' 2015-8-19 9:57:35 org.apache.catalina.core.ApplicationContext log 严重: StandardWrapper.Throwable org.springframework.beans.factory.BeanCreationException: Error cre

关于Springmvc中include与Sitemesh装饰器的基本使用

关于Springmvc中include与Sitemesh装饰器的使用 !!!转载请注明出处=>http://www.cnblogs.com/funnyzpc/p/7283443.html 静态包含:example:<%@include file="xxx.jsp"%> 文件的包含是发生在 jsp向servlet转换时期 ,相当于将jsp编译成html静态文件,由于对包含的文件不再编译(直接拷贝到父页面),则只产生一个class文件. 动态包含:example<j

详解SpringMVC中Controller的方法中参数的工作原理

前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:http://www.cnblogs.com/fangjian0423/p/springMVC-introduction.html SpringMVC中Controller的方法参数可以是Integer,Double,自定义对象,ServletRequest,ServletResponse,ModelAndView等等,非常灵活.本文将分析SpringMVC是如何对这些参数进行处理的,

在SpringMVC中 /* 和 / 的区别

<url-pattern> / </url-pattern>:会匹配到 /springmvc 这样的路径型url,而不会匹配到像 .jsp 这样的后缀型的url. <url-pattern> /* </url-pattern>:会匹配到所有的url:路径型url 和后缀型的url (包括/springmvc,.jsp,.js,和.html等). 在SpringMVC中需要添加这个标签:<mvc:default-servlet-handler />

springMVC 返回类型选择 以及 SpringMVC中model,modelMap.request,session取值顺序

springMVC 返回类型选择 以及 SpringMVC中model,modelMap.request,session取值顺序 http://www.360doc.com/content/14/0309/19/834950_359080244.shtml

springMVC中Dispatcher中的/和/*的区别

1. 首先 / 这个是表示默认的路径,及表示:当没有找到可以匹配的URL就用这个URL去匹配.2. 在springmvc中可以配置多个DispatcherServlet,比如: 配置多个DispatcherServlet有/和/*,先匹配的是/*这个 3. 当配置相同的情况下,DispathcherServlet配置成/和/*的区别< 一 > / :使用/配置路径,直接访问到jsp,不经springDispatcherServlet< 二 > /*:配置/*路径,不能访问到多视图的

详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析] good

目录 前言 现象 源码分析 HandlerMethodArgumentResolver与HandlerMethodReturnValueHandler接口介绍 HandlerMethodArgumentResolver与HandlerMethodReturnValueHandler接口的具体应用 常用HandlerMethodArgumentResolver介绍 常用HandlerMethodReturnValueHandler介绍 本文开头现象解释以及解决方案 编写自定义的HandlerMet

SpringMVC中出现&quot; 400 Bad Request &quot;错误(用@ResponseBody处理ajax传过来的json数据转成bean)的解决方法

最近angularjs post到后台 400一头雾水 没有任何错误. 最后发现好文,感谢作者 SpringMVC中出现" 400 Bad Request "错误(用@ResponseBody处理ajax传过来的json数据转成bean)的解决方法 今天开发过程中,在SpringMVC中的Action中处理前台ajax请求传过来的json数据直接转成对应的实体类时出错:400 Bad Request,后台也不报错,400指的的是请求无效(请求有语法问题或者不能满足请求),调试了好长时间