天天看點

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