天天看点

Java Web三大组件详解

作者:王朋code

前几天写了关于DispatcherServlet如何实例化的,今天我们来看一下java web的三大组件:Servlet、Filter、Listener。

不知道小伙伴们对这三个组件是否熟悉呢?感觉自从用了Spring框架后,很多组件都帮我们封装好了,感觉这三个里面,Filter是最常用的,至少我用过几次[泪奔]

Java Web三大组件详解

Listener简介

Listener表示服务器的事件监听器,用于监听三个域对象的状态(对象、对象的属性)变化,三个域对象分别是ServletContext、HttpSession、HttpServletRequest

Spring中可以使用ServletListenerRegistrationBean注册器进行注册监听

对于三大域对象,大家是否熟悉呢?改天写一篇关于三大域对象的文章

  • ServletContext

ServletContextListener:ServletContextListener负责监听 ServletContext 的创建和销毁,就可以监听服务器的启动和关闭。这样我们就可以在服务器启动和关闭的时候执行一些任务,比如服务器启动之后读取Spring Framework 的配置文件(applicationContext.xml),创建Spring的核心容器,我们的ContextLoaderListener就是实现了ServletContextListener,由AbstractContextLoaderInitializer进行注册,并初始化Spring的IOC容器的。

ServletContextAttributeListener:监听全局作用域对象共享数据变化时刻。当我向ServletContext域对象中添加修改删除值时,都可以通过监听获取到对应的动作。

  • HttpSession

HttpSessionListener:当一个浏览器第一次访问网站的时候,J2EE应用服务器会新建一个HttpSession对象 ,并触发 HttpSession创建事件 ,如果注册了HttpSessionListener事件监听器,则会调用HttpSessionListener事件监听器的 sessionCreated方法。相反,当这个浏览器访问结束超时的时候,J2EE应用服务器会销毁相应的HttpSession对象,触发 HttpSession销毁事件,同时调用所注册HttpSessionListener事件监听器的sessionDestroyed方法

HttpSessionActivationListener:实现了HttpSessionActivationListener接口的 JavaBean 对象可以感知自己被活化和钝化的事件。当绑定到 HttpSession 对象中的对象将要随 HttpSession 对象被钝化之前,web 服务器调用如下方法sessionWillPassivate(HttpSessionBindingEvent event) 方法;当绑定到 HttpSession 对象中的对象将要随 HttpSession 对象被活化之后,web 服务器调用该对象的 void sessionDidActive(HttpSessionBindingEvent event)方法。所谓的钝化状态,就是将Session内存中的对象持久化(序列化)到磁盘;活化状态,就是将磁盘上的对象再次恢复到session内存中。

HttpSessionBindingListener:实现BindingListener接口的对象被绑定到session时触发valueBound事件即setAttribute时,解除绑定即session销毁时触发valueUnbound事件。我们绑定到指定session中:session.setAttribute("名字",BindingListener接口实现对象);

HttpSessionAttributeListener:这个与ServletContextAttributeListener一样功能,监听的是HttpSession域对象中的内容

  • HttpServletRequest

ServletRequestListener:这个接口是在每次请求的时候就会执行监听,HttpServletRequest可以直接注入就是使用了ServletRequestListener接口监听了每次请求对象,相关文章:RequestObjectFactory()是怎么捕捉到每次请求的HTTP对象的

ServletRequestAttributeListener:这个与ServletContextAttributeListener一样的功能,只是监听的是HttpServletRequest域对象中的内容

Filter简介

当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊功能,例如:登录验证、统一编码处理、敏感字符过滤……

鄙人曾经使用Filter进行了ServletRequest包装处理,从而可以使ServletRequest可以多次读取,因为ServletRequest的getInputStream方法只能使用一次,但是我还想在到达Controller之前用拦截器对请求内容进行一次处理,因此我使用过滤器将ServletRequest包装一下。

@WebFilter(urlPatterns = "/*")
@Order(Ordered.HIGHEST_PRECEDENCE)
public class RequestWrapperFilter extends GenericFilterBean {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        //将ServletRequest封装一下,因为request.getInputStream()方法只能读取一次,所以不能和@requestBody一起使用
        ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper((HttpServletRequest) request);
        log.info("WebRqsTypeChangeFilter----->"+new String(requestWrapper.getBody()));
        chain.doFilter(requestWrapper, response);
    }

}
//也可以使用下面这种方式进行注册过滤器,也可以直接使用@WebFilter注解
@Bean
public FilterRegistrationBean<GenericFilterBean> jwtFilter() throws NoSuchAlgorithmException {
  FilterRegistrationBean<GenericFilterBean> registration = new FilterRegistrationBean<>();
  registration.setFilter(new RequestWrapperFilter());
  registration.addUrlPatterns("/api/*");
  registration.setOrder(2);
  return registration;
}           

Servlet简介

Servlet(Server Applet)服务器的小程序。是用java编写的一个服务器程序,目的是和浏览器交互并且生成动态的web内容。Servlet狭义上来讲指的是servlet接口,广义上来讲指的是所有实现接口的实现类。

Servlet是指实现了Servlet接口类,Servlet运行于支持java的应用服务器(tomcat,Servlet是tomcat的一个组件)中。从原理上来讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务

Servlet生命周期:从创建到销毁的全过程,共分为三个阶段

  1. 初始化init方法: 只会执行一次(启动tomcat的时候默认是不执行的,在访问的时候才会执行)
  2. 服务方法service: 可以执行多次,每次请求会执行
  3. 销毁方法destory: 只执行一次(停止服务器)
//简单创建一个Servlet
@WebServlet(urlPatterns = "/demo",name = "demo")
public class Demo implements Servlet {
    /**
     * 最开始被调用,初始化servlet,初始化一次之后不再被调用;因此servlet是一个单例线程不安全的对象。
     * @param config
     * @throws ServletException
     */
    @Override
    public void init(ServletConfig config) throws ServletException {

    }
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }
    /**
     * 逻辑处理方法,接收响应,处理请求,具体的实现在此方法中
     * @param req
     * @param res
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {

    }
    @Override
    public String getServletInfo() {
        return null;
    }
    /**
     * 调用此方法销毁servlet
     */
    @Override
    public void destroy() {

    }
}           

组件调用顺序

三大组件初始化顺序与销毁顺序

初始化:Listener->Filter->Servlet

销毁:Servlet->Filter->Listener