Java Web高級編程(三)

来源:http://www.cnblogs.com/winterfells/archive/2017/12/11/8024209.html
-Advertisement-
Play Games

使用過濾器改進應用程式 一、過濾器的目的 過濾器是可以攔截訪問資源的請求、資源的響應或者同時攔截兩者的應用組件。過濾器可以檢測和修改請求和響應,同時也可以拒絕、重定向或轉發請求。javax.servlet.Filter介面實現了過濾器技術,使用HttpServletRequest和HttpServl ...


使用過濾器改進應用程式

一、過濾器的目的

過濾器是可以攔截訪問資源的請求、資源的響應或者同時攔截兩者的應用組件。過濾器可以檢測和修改請求和響應,同時也可以拒絕、重定向或轉發請求。javax.servlet.Filter介面實現了過濾器技術,使用HttpServletRequest和HttpServletResponse。過濾器可以在部署描述符中以以編程的方式聲明,它們可以有初始化參數並且可以訪問ServletContext。

日誌過濾器

在應用程式開發中,需要記錄所有應用程式的請求和每個請求的結果(狀態碼,長度等其它信息)。通常Web容器提供了請求日誌的機制,但如果需要在請求日誌中顯示出一些特有的信息,可以使用過濾記錄請求。

驗證過濾器

如果需要確保只有授權用戶才可以訪問應用程式,通常可以檢查每個請求的信息,保證用戶已登錄,過濾器可以通過將驗證和授權操作集中到一個位置的方式使工作變得簡單。

壓縮和加密過濾器

存在著網路帶寬有限而CPU資源充足的情況,通常在數據傳輸之前對數據進行壓縮。過濾器可以在收到請求時,請求保持不變,但在響應返回給用戶時,使用過濾器可以壓縮相應對象。

錯誤處理過濾器

對於Web用用程式而言,出現錯誤,是一個HTTP響應代碼500,一般還會伴隨著一個普通的HTML頁面,寫著“Internal Server Error”以及一些診斷信息。對於在本地運行的應用程式對開發者是有用的,但是對於遠程的應用程式來說是不必要的。需要通過過濾器給用戶顯示出更加友好的和通用的錯誤處理頁面,並記錄必要的錯誤信息。

二、創建、聲明和映射過濾器

創建過濾器就是實現Filter介面一樣,過濾器在初始化的時候將調用init方法,他可以訪問過濾器的配置初始化參數和ServletContext。當請求進入到過濾器中,doFilter方法將會被調用,它提供了對ServletRequest、ServletResponse和FilterChain對象的訪問。在doFilter中,可以拒絕請求或者調用FilterChain對象的doFilter方法,可以封裝請求和響應對象。

過濾器鏈

儘管只有一個Servlet可以處理請求,但是可以使用許多的過濾攔截請求。在過濾器鏈中每一個過濾器接受進入的請求並將它傳遞到下一個過濾鏈中,直到所有匹配的過濾器都處理完成,最終再將它傳入Servlet中。調用FilterChain.doFilter()將觸發過濾器鏈的持續執行。如果當前的過濾器沒有調用FilterChain.doFilter(),將把控制權返回值Servlet容器中。

映射到URL模式和Servlet名稱

同Servlet一樣,過濾器可以被映射到URL模式,這會決定哪個或哪些過濾器將攔截某個請求。任何匹配某個過濾器的URL模式的請求在被匹配的Servlet處理之前將首先進入該過濾器,通過使用URL模式,不僅可以攔截Servlet請求,還可以攔截其它資源。

但是當現在已經有多個URL已經映射到Servlet上,並且希望某些過濾器映射到這些URL上。與映射到URL上相反,可以將這些過濾器映射到一個或多個Servlet名稱上。

1.在部署描述符中使用<filter>和<filter-mapping>元素:

    <filter>
        <filter-name>filterA</filter-name>
        <filter-class>com.wrox.AnyRequestFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>filterA</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

在聲明瞭過濾器之後,可以將它映射到任意數目的URL或Servlet名稱。當然過濾器URL映射還可以包含通配符。

2.使用註解聲明和映射過濾器

@WebFilter{
    filterName = "myFilter",
    urlPatterns = {"/foo","/bar/*"},
    serVletNames = {"myServlet"},
    dispatcherTypes = {DispatcherType.REQUEST,         
    DispatcherType.ASYNC}    
}

但是不可以對對過濾器鏈上的過濾器進行排序

三、過濾器排序

過濾器的順序決定了過濾器在過濾器鏈中出現的位置,這裡將會使用部署描述符來進行配置,因為註解無法進行排序配置。

URL模式映射和Servlet名稱映射,匹配請求的過濾器將按照它們出現在部署描述符或者編程式配置中的順序添加到過濾器鏈中,但是需要註意URL映射的過濾器優先順序比Servlet名稱映射到的過濾器高,由URL模式匹配的過濾器總是出現在有Servlet名稱匹配的過濾器之前。

    <filter>
        <filter-name>filterA</filter-name>
        <filter-class>com.wrox.FilterA</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>filterA</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>filterB</filter-name>
        <filter-class>com.wrox.FilterB</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>filterB</filter-name>
        <url-pattern>/servletTwo</url-pattern>
        <url-pattern>/servletThree</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>filterC</filter-name>
        <filter-class>com.wrox.FilterC</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>filterC</filter-name>
        <url-pattern>/servletTwo</url-pattern>
    </filter-mapping>

這是一個filter的實例:

這是處理中的第一個過濾器,它將記錄處理請求的時間,並記錄所有訪問應用程式的請求信息——IP地址、時間戳、請求方法等信息,finally塊中是日誌的操作。

public class RequestLogFilter implements Filter
{
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException
    {
        Instant time = Instant.now();
        StopWatch timer = new StopWatch();
        try
        {
            timer.start();
            chain.doFilter(request, response);
        }
        finally
        {
            timer.stop();
            HttpServletRequest in = (HttpServletRequest)request;
            HttpServletResponse out = (HttpServletResponse)response;
            String length = out.getHeader("Content-Length");
            if(length == null || length.length() == 0)
                length = "-";
            System.out.println(in.getRemoteAddr() + " - - [" + time + "]" +
                    " \"" + in.getMethod() + " " + in.getRequestURI() + " " +
                    in.getProtocol() + "\" " + out.getStatus() + " " + length +
                    " " + timer);
        }
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException { }

    @Override
    public void destroy() { }
}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • WebSocket 一、WebSocket的產生 用戶希望Web頁面可以進行交互,用於解決這個問題的技術是JavaScript,現在Web上有許多的可用的JavaScript框架,在使用極少的JavaScript的情況下就可以創建出豐富的單頁面Web——Ajax技術(非同步JavaScript和XML ...
  • 十六進位數和十進位數類似,以小數點為界,整數部分從低位到高位依次是0次方位、1次方位、.、n次方位;小數部分從高位到低位依次是-1次方位、-2次方位、.、-m次方位.都可用加權求和的方式表示.十六進位數轉換成十進位數時,先用加權求和的方式表示出來,再將十六進位數中的基數“10H”替換成對應的十進位數 ...
  • 首先,把連接資料庫的語句做成工具類,因為會一直用到這幾句 代碼如下: 工具里包含兩個靜態方法都可以直接使用,一個是獲得連接getConn得到連接類Connection的對象,後面連接資料庫直接DBUtil.getConn()就可以了 還有一個是用完資料庫要關閉與資料庫的連接,使用DBUtil.clo ...
  • 1. 創建Java的類 如果說Java的一切都是對象,那麼類型就是決定了某一類對象的外觀與行為。可是類型的關鍵字不是type,而是class,創建一個新的類型要用下麵的代碼: 1 2 3 class AClassName{ //類型的主體 } 1 2 3 class AClassName{ //類型 ...
  • Description 輸入一個正整數n,求有幾對素數x,y,滿足n=x+y((3,2)和(2,3)視為相同的素數對)。 Input 有多組數據,每行輸入一個偶整數n(3<n<32768)。n等於0時,輸入結束。 Output 輸出相應的答案。 Sample Input 6 10 12 0 Samp ...
  •   在分析了hashCode方法和equals方法之後,我們對hashCode方法和equals方法的相關作用有了大致的瞭解。在通過查看HashMap類的相關源碼的時候,發現其中存在一個int hash(int h)的方法。在HashMap中該方法的源碼如下:  &em ...
  • 文章核心 其實,本不想把標題寫的那麼恐怖,只是發現很多人幹了幾年java以後,都自認為是一個不錯的java程式員了,可以拿著上萬的工資都處宣揚自己了,寫這篇文章的目的並不是嘲諷和我一樣做java的同行們,只是希望讀者看到此篇文章後,可以和我一樣,心平氣和的爭取做一個優秀的程式員。 講述方向 由於一直 ...
  • Properties類與.properties文件:   Properties類繼承自Hashtable類並且實現了Map介面,也是使用一種鍵值對的形式來保存屬性集的類,不過Properties有特殊的地方,就是它的鍵和值都是字元串類型。而.properties文件是由“鍵=值” ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...