日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java Servlet 过滤器与 springmvc 拦截器的区别?

發布時間:2023/12/10 java 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java Servlet 过滤器与 springmvc 拦截器的区别? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言:在工作中,遇到需要記錄日志的情況,不知道該選擇過濾器還是攔截器,故總結了一下。

servlet 過濾器

定義

  java過濾器能夠對目標資源的請求和響應進行截取。過濾器的工作方式分為四種

應用場景

  可以通過 doFilter 方法的?request、response 提前過濾一些不想要的信息,統一設置一些參數、統一設置字符集、控制權限是否登錄等。

配置  

<!-- 定義Filter --><filter><!-- Filter的名字 --><filter-name>loginFilter</filter-name><!-- Filter的實現類 --><filter-class>com.yule.common.filters.LoginFilter</filter-class></filter><!-- 定義Filter攔截的URL地址 --><filter-mapping><!-- Filter的名字 --><filter-name>loginFilter</filter-name><!-- Filter負責攔截的URL 全部以/的請求,如果/*,將會所有的請求--><url-pattern>/*</url-pattern></filter-mapping>

過濾器的4種工作方式

<filter-mapping><filter-name>myFilter</filter-name><servlet-name>目標資源</servlet-name><dispatcher>REQUEST</dispatcher> </filter-mapping>

  四中工作方式通過配置?<dispatcher> 標簽來決定

  • request 過濾器:不配 <dispatcher> 標簽,或者配置為?<dispatcher>REQUEST</dispatcher> 。說明只有直接訪問該目標資源時該過濾器才會起作用,對轉發到該目標資源的請求將忽略不處理。
  • forward 過濾器:配置為?<dispatcher>FORWARD</dispatcher> 。表示對轉發到目標資源的請求過濾,如果直接訪問目標資源,過濾器則不起作用。
  • include 過濾器:配置為?<dispatcher>INCLUDE</dispatcher> 。表示對包含了目標資源的請求過濾,如果直接訪問目標資源,則此過濾器將不起作用 include 包含以下語句: 在 JSP 頁面中的動作:<jsp:include page=....... 在 Java 代碼中的 request.getRequestDispatcher("....").include 注意:如果目標資源一通過 <%@ include file="目標資源二"%> 指令包含,這時此過濾器不工作,因為這個是指令,在JSP 編譯時插入一個包含文本或代碼的文件,這個包含的過程是靜態的。
  • error 過濾器:配置為 <filter-mapping><filter-name>myFilter</filter-name><url-pattern>/error.jsp</url-pattern><dispatcher>ERROR</dispatcher> </filter-mapping><error-page><error-code>404</error-code><location>/error.jsp</location> </error-page> 當我們訪問一個web目標資源時,如果服務器沒有找到該目標資源,那么服務器就會給出一個404錯誤代碼。如果我們給404錯誤代碼定義一個頁面,那么當404發生時就會調用該頁面。 當我們訪問一個不存在的文件時,就會訪問error.jsp,但是配置了過濾器對錯誤頁面進行過濾,所以過濾器先接受到請求,然后再轉發給error.jsp。 如果我們訪問一個已經存在的頁面,會不會調用error.jsp呢?如果這個頁面中有response.sendError(404,"出錯了!");那么該錯誤頁面仍然會被調用,過濾器也會工作。
  • 執行順序

      根據 web.xml 的代碼順序來決定過濾器的執行順序。Filter 鏈:?一個Web應用中,可以編寫多個Filter,這些 Filter 組合起來稱之為一個Filter鏈。

      當第一個 Filter 的 doFilter 方法被調用時,web 服務器會創建一個代表 Filter 鏈的 FilterChain 對象傳遞給該方法。在 doFilter 方法中,如果調用了 FilterChain 對象的 doFilter 方法,則 web 服務器會檢 FilterChain 對象中是否還有 filter ,如果有,則調用第下一個 filter,如果沒有,則調用目標資源。

      init() 方法和?destroy() 方法隨著項目的啟動和關閉才會被調用,且僅一次。

    舉個栗子

      web.xml 中

    <!-- 定義Filter --><filter><!-- Filter的名字 --><filter-name>demoFilter</filter-name><!-- Filter的實現類 --><filter-class>com.yule.common.filters.DemoFilter</filter-class></filter><!-- 定義Filter攔截的URL地址 --><filter-mapping><!-- Filter的名字 --><filter-name>demoFilter</filter-name><!-- Filter負責攔截的URL 全部以/的請求,如果/*,將會所有的請求--><url-pattern>/*</url-pattern></filter-mapping>

      Java 代碼

    package com.yule.common.filters;import javax.servlet.*; import java.io.IOException;/*** 過濾器* @author yule* @date 2018/7/2 21:52*/ public class DemoFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("demo過濾器init。。。");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("demo過濾器doFilter。。。此處省略業務處理邏輯");//通過判斷是否繼續往下走 filterChain.doFilter(servletRequest, servletResponse);}@Overridepublic void destroy() {System.out.println("demo過濾器destroy。。。");} }

    ?

    springmvc 攔截器

    定義

      springMVC 攔截器源碼解析

      Spring Web MVC的處理器攔截器。類似于Servlet開發中的過濾器Filter,用于對處理器進行預處理和后處理。攔截器是面向切面編程的,依賴的技術就是Java的動態代理。

    應用場景

  • 日志記錄:記錄請求日志等。
  • 權限檢查:白名單等;
  • 性能監控:可以通過攔截器在進入處理器之前記錄開始時間,在處理完后記錄結束時間,從而得到該請求的處理時間;
  • 通用行為:讀取cookie得到用戶信息并將用戶對象放入請求,從而方便后續流程使用,還有如提取Locale、Theme信息等,只要是多個處理器都需要的即可使用攔截器實現。
  • OpenSessionInView:如Hibernate,在進入處理器打開Session,在完成后關閉Session。
  •   本質是AOP(面向切面編程),符合 AOP 的所有功能都可以使用攔截器實現。

    配置

      在 spring-mvc.xml 中

    <mvc:interceptors><!-- 使用bean定義一個Interceptor,直接定義在mvc:interceptors根下面的Interceptor將攔截所有的請求 --><!-- <bean class="com.bybo.aca.web.interceptor.Login"/> --><mvc:interceptor><!--進行攔截的地址--><mvc:mapping path="/**"/><bean class="com.yule.common.interceptors.DemoInterceptor"/></mvc:interceptor></mvc:interceptors>

    執行順序

      根據 xml 中的配置順序來執行。攔截器的執行順序在過濾器之間。

    方法說明

    • preHandle(HttpServletRequest request, HttpServletResponse response, Object handle)方法,該法在請求處理之前進行調用。SpringMVC 中的 Interceptor 是鏈式調用的,在一個應用中或者說是在一個請求中可以同時存在多個 Interceptor 。每個 Interceptor 的調用會依據它的聲明順序依次執行,而且最先執行的都是 Interceptor 中的 preHandle 方法,所以可以在這個方法中進行一些前置初始化操作或者是對當前請求做一個預處理,也可以在這個方法中進行一些判斷來決定請求是否要繼續進行下去。該方法的返回值是布爾值 Boolean 類型的,當它返回為 false 時,表示請求結束,后續的 Interceptor 和 Controller 都不會再執行;當返回值為 true 時,就會繼續調用下一個 Interceptor 的 preHandle 方法,如果已經是最后一個 Interceptor 的時候,就會是調用當前請求的 Controller 中的方法。
    • postHandle(HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView)方法,通過 preHandle 方法的解釋咱們知道這個方法包括后面要說到的 afterCompletion 方法都只能在當前所屬的 Interceptor 的 preHandle 方法的返回值為 true 的時候,才能被調用。postHandle 方法在當前請求進行處理之后,也就是在 Controller 中的方法調用之后執行,但是它會在 DispatcherServlet 進行視圖返回渲染之前被調用,所以咱們可以在這個方法中對 Controller 處理之后的 ModelAndView 對象進行操作。postHandle 方法被調用的方向跟 preHandle 是相反的,也就是說,先聲明的 Interceptor 的 postHandle 方法反而會后執行。
    • afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex)方法,也是需要當前對應的 Interceptor 的 preHandle 方法的返回值為 true 時才會執行。因此,該方法將在整個請求結束之后,也就是在 DispatcherServlet 渲染了對應的視圖之后執行,這個方法的主要作用是用于進行資源清理的工作。afterCompletion 方法被調用的方向也跟 preHandle 是相反的,也就是說,先聲明的 Interceptor 的 afterCompletion 方法反而會后執行

    舉個栗子

      spring-mvc 中

    <mvc:interceptors><!-- 使用bean定義一個Interceptor,直接定義在mvc:interceptors根下面的Interceptor將攔截所有的請求 --><!-- <bean class="com.bybo.aca.web.interceptor.Login"/> --><mvc:interceptor><!--進行攔截的地址--><mvc:mapping path="/**"/><bean class="com.yule.common.interceptors.DemoInterceptor"/></mvc:interceptor></mvc:interceptors>

      Java 代碼

    package com.yule.common.interceptors;import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;/*** 自定義攔截器方式一* Created by yule on 2018/7/2 22:37.*/ public class DemoInterceptor implements HandlerInterceptor{@Overridepublic boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {//return true 表示繼續下一個攔截器或者 control 層//return false 表示被攔截下來return false;}@Overridepublic void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {}@Overridepublic void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {} } package com.yule.common.interceptors;import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;/*** 自定義攔截器方式二* 一般都是通過實現HandlerInterceptor接口或者繼承HandlerInterceptorAdapter抽象類,復寫preHandle()、postHandle()和afterCompletion()這 3 個方法來對用戶的請求進行攔截處理* Created by yule on 2018/7/2 22:43.*/ public class Demo2Interceptor extends HandlerInterceptorAdapter {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {return true;} }

    ?區別

      其實兩者還是有相似之處,就是都可以用作權限檢查、日志記錄等情況,但是在這些情況下如何選擇就要知道不同之處。

    不同之處

      使用范圍不同:Filter 只能用于 Web 程序中。而攔截器可以用于 Web 程序,Application、Swing 程序中。

      規范不同:Filter 是 servlet 規范規定的,是 servlet 支持的。而攔截器是在 spring 容器內,是 spring 框架支持的。

      使用資源不同:Filter 不能直接使用 spring 的資源、對象等。而攔截器是一個 spring 組件,歸 spring 管理,配置在 spring 文件中,因此能使用 spring 的任何資源、對象,例如 Service 對象、數據源、事務管理等,通過 IoC 注入到攔截器即可。也就是說在攔截器中可以注入一個 service ,用于業務邏輯或者訪問數據庫。

      深度不同:Filter 只在 Servlet 前后起作用。而攔截器能夠深入到方法前后、異常拋出前后等,因此攔截器的使用具有更大的彈性。

      作用范圍不同:攔截器只能對 Controller 層請求起作用,而過濾器則可以對幾乎所有的請求起作用(如 .js、.css等)。

      所以,在 Spring 構架的程序中,要優先使用攔截器。

    注意

      攔截器是在過濾器之間運行的。

    執行順序舉例

    攔截器,spring-mvc.xml 中:

    <mvc:interceptors><!-- 使用bean定義一個Interceptor,直接定義在mvc:interceptors根下面的Interceptor將攔截所有的請求 --><!-- <bean class="com.bybo.aca.web.interceptor.Login"/> --><mvc:interceptor><!--進行攔截的地址--><mvc:mapping path="/**"/><bean class="com.yule.common.interceptors.DemoInterceptor"/></mvc:interceptor><mvc:interceptor><!--進行攔截的地址--><mvc:mapping path="/**"/><bean class="com.yule.common.interceptors.Demo2Interceptor"/></mvc:interceptor></mvc:interceptors>

    java 代碼:

    package com.yule.common.interceptors;import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;/*** 自定義攔截器方式一* Created by yule on 2018/7/2 22:37.*/ public class DemoInterceptor implements HandlerInterceptor{@Overridepublic boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {//return true 表示繼續下一個攔截器或者 control 層//return false 表示被攔截下來System.out.println("preHandle");return true;}@Overridepublic void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {System.out.println("postHandle");}@Overridepublic void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {System.out.println("afterCompletion");} } View Code package com.yule.common.interceptors;import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;/*** 自定義攔截器方式二* 一般都是通過實現HandlerInterceptor接口或者繼承HandlerInterceptorAdapter抽象類,復寫preHandle()、postHandle()和afterCompletion()這 3 個方法來對用戶的請求進行攔截處理* Created by yule on 2018/7/2 22:43.*/ public class Demo2Interceptor extends HandlerInterceptorAdapter {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("preHandle 2222222...");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("postHandle 22222222");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("afterCompletion 2222222");} } View Code

    過濾器, web.xml 中:

    <!-- 定義Filter --><filter><!-- Filter的名字 --><filter-name>demoFilter</filter-name><!-- Filter的實現類 --><filter-class>com.yule.common.filters.DemoFilter</filter-class></filter><!-- 定義Filter攔截的URL地址 --><filter-mapping><!-- Filter的名字 --><filter-name>demoFilter</filter-name><!-- Filter負責攔截的URL 全部以/的請求,如果/*,將會所有的請求--><url-pattern>/*</url-pattern></filter-mapping><filter><filter-name>demo2Filter</filter-name><filter-class>com.yule.common.filters.Demo2Filter</filter-class></filter><filter-mapping><filter-name>demo2Filter</filter-name><url-pattern>/*</url-pattern></filter-mapping>

    java 代碼:

    package com.yule.common.filters;import javax.servlet.*; import java.io.IOException;/*** 過濾器* @author yule* @date 2018/7/2 21:52*/ public class DemoFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("demo過濾器init。。。");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("demo過濾器doFilter。。。此處省略業務處理邏輯");//通過判斷是否繼續往下走 filterChain.doFilter(servletRequest, servletResponse);}@Overridepublic void destroy() {System.out.println("demo過濾器destroy。。。");} } View Code package com.yule.common.filters;import javax.servlet.*; import java.io.IOException;/*** Created by yule on 2018/7/2 22:18.*/ public class Demo2Filter implements Filter{@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("demo2過濾器init 2222222");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("demo過濾器doFilter 222222");//通過判斷是否繼續往下走 filterChain.doFilter(servletRequest, servletResponse);}@Overridepublic void destroy() {System.out.println("demo2過濾器destroy 22222 ");} } View Code

    調用 controller 打印結果:

    ?

    轉載于:https://www.cnblogs.com/yuxiaole/p/9230742.html

    總結

    以上是生活随笔為你收集整理的Java Servlet 过滤器与 springmvc 拦截器的区别?的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。