Java高級 | 【實驗七】Springboot 過濾器和攔截器

隸屬文章:Java高級 | (二十二)Java常用類庫-CSDN博客

系列文章:Java高級 | 【實驗一】Springboot安裝及測試 |最新-CSDN博客

? ? ? ? ? ? ? ? ??Java高級 | 【實驗二】Springboot 控制器類+相關注解知識-CSDN博客

? ? ? ? ? ? ? ? ??Java高級 | 【實驗三】Springboot 靜態資源訪問-CSDN博客

? ? ? ? ? ? ? ? ??Java高級 | 【實驗四】Springboot 獲取前端數據與返回Json數據-CSDN博客

? ? ? ? ? ? ? ? ??Java高級 | 【實驗五】Spring boot+mybatis操作數據庫-CSDN博客

? ? ? ? ? ? ? ? ??Java高級 | 【實驗六】Springboot文件上傳和下載-CSDN博客

目錄

一、【過濾器】Filter

1.1 過濾器的功能

1.2 過濾器的工作原理

二、過濾器實驗

2.1 實驗項目結構

2.2?源碼

(1)CorsFilter類

(2)FilterConfig類

(3)TimingFilter類

(4)TestController控制器類

2.3測試

(1)postman中測試結果

(2)Idea控制臺輸出的結果

三、【攔截器】interceptor

3.1 Interceptor使用場景

3.2 實現

3.3 工作/運行流程

四、?攔截器實驗

4.1 新建工程

4.2 編寫代碼

(1)實體類

(2)攔截器類

(3)配置攔截器類

(4)編寫控制器類

(5)創建前端頁面

(6)修改主類

4.3 測試

一、【過濾器】Filter

? ? ? ?過濾器是對數據進行過濾,預處理過程,當我們訪問網站時,有時候會發布一些敏感信息,發完以后有的會用*替代,還有就是登陸權限控制等,一個資源,沒有經過授權,肯定是不能讓用戶隨便訪問的,這個時候,也可以用到過濾器。

1.1 過濾器的功能

還有很多,例如實現URL級別的權限控制、壓縮響應信息、編碼格式等等。攔截掉我們不需要的接口請求,修改請求(request)和響應(response)內容,完成CORS跨域請求等等。

1.2 過濾器的工作原理

二、過濾器實驗

2.1 實驗項目結構

? ? ? Myfilter包中定義了兩個過濾器類和一個過濾器配置類:

  • CorsFilter跨域處理
  • FilterConfig:配置兩個過濾器
  • TimingFilter:記錄請求時間

2.2?源碼

(1)CorsFilter類

package myfilter;import jakarta.servlet.*;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.core.annotation.Order;import java.io.IOException;
@WebFilter
public class CorsFilter implements Filter {// 初始化方法(Filter 容器啟動時調用一次)@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("CorsFilter 初始化完成");}// 核心過濾方法(每個請求觸發一次)@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {HttpServletResponse httpResponse = (HttpServletResponse) response;httpResponse.setHeader("Access-Control-Allow-Origin", "*");httpResponse.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");System.out.println("CorsFilter 前置處理");chain.doFilter(request, response); // 繼續后續處理System.out.println("CorsFilter 后置處理");}// 銷毀方法(應用關閉時調用一次)@Overridepublic void destroy() {System.out.println("CorsFilter 銷毀");}
}

(2)FilterConfig

package myfilter;import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FilterConfig {// 注冊 TimingFilter(順序1)@Beanpublic FilterRegistrationBean<TimingFilter> timingFilterRegistration() {FilterRegistrationBean<TimingFilter> registration = new FilterRegistrationBean<>();registration.setFilter(new TimingFilter());registration.addUrlPatterns("/*"); // 攔截所有路徑registration.setOrder(1); // 優先級最高(數值越小優先級越高)return registration;}// 注冊 CorsFilter(順序2)@Beanpublic FilterRegistrationBean<CorsFilter> corsFilterRegistration() {FilterRegistrationBean<CorsFilter> registration = new FilterRegistrationBean<>();registration.setFilter(new CorsFilter());registration.addUrlPatterns("/*");registration.setOrder(2); // 優先級次之return registration;}
}

(3)TimingFilter類

package myfilter;import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter // 可選注解(需配合 @ServletComponentScan)
public class TimingFilter implements Filter {private long startTime; // 記錄請求開始時間// 初始化方法(Filter 容器啟動時調用一次)public void init(FilterConfig filterConfig) throws ServletException {System.out.println("TimingFilter 初始化完成");// 可讀取 Filter 配置參數(如 filterConfig.getInitParameter("key"))}// 核心過濾方法(每個請求觸發一次)@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {startTime = System.currentTimeMillis();System.out.println("TimingFilter 前置處理開始");// 繼續 Filter 鏈或 Controllerchain.doFilter(request, response);long endTime = System.currentTimeMillis();System.out.println("TimingFilter 后置處理,總耗時:" + (endTime - startTime) + "ms");}// 銷毀方法(應用關閉時調用一次)@Overridepublic void destroy() {System.out.println("TimingFilter 銷毀");}
}

(4)TestController控制器

package controller;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {@GetMapping("/test")public String test() {System.out.println("Controller 方法執行");return "Hello from Controller!";}
}

(5)修改MyfilterApplication主類

package com.example.myfilter;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan(basePackages = {"controller"})
@ComponentScan(basePackages = {"myfilter"})
public class MyfilterApplication {public static void main(String[] args) {SpringApplication.run(MyfilterApplication.class, args);}
}

2.3測試

(1)postman中測試結果

(2)Idea控制臺輸出的結果



攔截器】interceptor

? ? ? ?攔截器(Interceptor)同 Filter 過濾器一樣,它倆都是面向切面編程——AOP 的具體實現(AOP切面編程只是一種編程思想而已)。

  • 使用 Interceptor 來執行某些任務,例如在 Controller 處理請求之前編寫日志,添加或更新配置等等
  • 在 Spring中,當請求發送到Controll時,在被Controller處理之前,它必須經過 Interceptors(0或多個)。

3.1 Interceptor使用場景

日志記錄:記錄請求信息的日志,以便進行信息監控、信息統計、計算 PV(Page View)等;

權限檢查:如登錄檢測,進入處理器檢測是否登錄;

性能監控:通過攔截器在進入處理器之前記錄開始時間,在處理完后記錄結束時間,從而得到該請求的處理時間。(反向代理,如 Apache 也可以自動記錄)

通用行為:讀取 Cookie、session、header等?得到用戶信息并將用戶對象放入請求,從而方便后續流程使用。?

3.2 實現

通常用戶可以自定義攔截器。

自定義 Interceptor 必須實現 org.springframework.web.servlet.HandlerInterceptor接口或繼承 org.springframework.web.servlet.handler.HandlerInterceptorAdapter類,并且需要重寫下面下面 3 個方法:

3.3 工作/運行流程

1、攔截器執行順序是按照Spring配置文件中定義的順序而定的。

2、會先按照順序執行所有攔截器的preHandle方法,一直遇到return false為止,比如第二個preHandle方法是return false,則第三個以及以后所有攔截器都不會執行。若都是return true,則按順序加載完preHandle方法。

3、然后執行主方法(自己的controller接口),若中間拋出異常,則跟return false效果一致,不會繼續執行postHandle,只會倒序執行afterCompletion方法。

4、在主方法執行完業務邏輯(頁面還未渲染數據)時,按倒序執行postHandle方法。若第三個攔截器的preHandle方法return false,則會執行第二個和第一個的postHandle方法和afterCompletion(postHandle都執行完才會執行這個,也就是頁面渲染完數據后,執行after進行清理工作)方法。(postHandle和afterCompletion都是倒序執行)。

四、?攔截器實驗

4.1 新建工程

工程名稱為“test_interceptor”,創建工程的時候勾選Lombok、Spring Web、Thymeleaf。

工程創建完畢后在java包中創建bean、config、controller、interceptor等四個包。

本實驗完整的工程圖如下圖所示:

4.2 編寫代碼

(1)實體類

在bean包中創建User類,其代碼如下:

package bean;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Data
public class User {private String userName;private String password;
}

(2)攔截器類

在interceptor包中創建一個名為“LoginInterceptor”類,該類實現了HandlerInterceptor接口,說明該類是一個攔截器類。其代碼如下:

package interceptor;import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {// 目標方法執行之前@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 攔截請求輸出String requestURI = request.getRequestURI();log.info("攔截了請求{}", requestURI);// 登錄檢查邏輯,是否登錄,登錄成功以后放行資源,未登錄則攔截資源HttpSession session = request.getSession();Object loginUser = session.getAttribute("loginUser");if (loginUser != null) {// 登錄成功放行資源return true;} else {// 提示錯誤信息request.setAttribute("msg", "請先登錄!");// 請求轉發request.getRequestDispatcher("/").forward(request, response);// 未登錄攔截資源return false;}}// 目標方法執行完畢@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {log.info("postHandle執行{}",modelAndView);}// 頁面渲染以后@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {log.info("afterCompletion執行異常{}",ex);}
}

(3)配置攔截器類

該類主要功能是攔截哪些請求和不攔截哪些請求。

在config包中創建一個名為“MyWebConfig”的類,該類實現了WebMvcConfigurer接口。其代碼如下:

package config;import interceptor.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
// 自定義springboot配置類
@Configuration
public class MyWebConfig implements WebMvcConfigurer {// 添加注冊攔截器@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**") // 攔截所有請求.excludePathPatterns("/","/login","/mylogin"); // 放行請求//平常可以寫這樣             // .excludePathPatterns("/","/login","/css/**","/js/**","/fonts/**","/images/**");}
}

(4)編寫控制器類

在controller包中編寫一個名為“LoginController”的類,該類的代碼如下啊:

package controller;import bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
public class LoginController {@PostMapping("/mylogin")public String login(User user, Model model){System.out.println(user);if ("robin".equals(user.getUserName())&&"123456".equals(user.getPassword())){model.addAttribute("loginUser",user);return "show";}else{model.addAttribute("msg","登錄失敗,請檢查賬號密碼信息..");return "login";}}@RequestMapping("/login")public String ft_login() {return "login";}@RequestMapping("/show")public String ft_show() {return "show";}
}

(5)創建前端頁面

login.html的代碼:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>登錄頁面</title>
</head>
<body>
<h3 th:text="${msg}">title</h3>
<form action="/login" method="post"><input type="text" name="userName"><br><input type="password" name="password"><br><input type="submit" value="登錄">
</form>
</body>
</html>

show.html的代碼:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>顯示頁面</title>
</head>
<body>
<h3 th:text="${msg}">title</h3>
賬號:<p th:text="${loginUser.userName}">賬號xxx</p>
密碼:<p th:text="${loginUser.password}">密碼xxx</p>
</body>
</html>

(6)修改主類

在TestInterceptorApplication類中加入注解,注入控制器類和web配置類。修改后的代碼如下:

package com.example.test_interceptor;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan(basePackages = {"controller"})
@ComponentScan(basePackages = {"config"})
public class TestInterceptorApplication {public static void main(String[] args) {SpringApplication.run(TestInterceptorApplication.class, args);}}

4.3 測試

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/908480.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/908480.shtml
英文地址,請注明出處:http://en.pswp.cn/news/908480.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【圖片識別改名】如何批量將圖片按圖片上文字重命名?自動批量識別圖片文字并命名,基于圖片文字內容改名,WPF和京東ocr識別的解決方案

應用場景 在日常工作和生活中&#xff0c;我們經常會遇到需要對大量圖片進行重命名的情況。例如&#xff0c;設計師可能需要根據圖片內容為設計素材命名&#xff0c;文檔管理人員可能需要根據掃描文檔中的文字對圖片進行分類命名。傳統的手動重命名方式效率低下且容易出錯&…

防火墻iptables項目實戰

目錄 一、網絡規劃 三、環境準備與檢測 1、firewall &#xff08;1&#xff09;配置防火墻各大網卡ip并禁用firewalld和selinux &#xff08;2&#xff09;打開firewall路由轉發 2、PC1&#xff08;內網&#xff09; &#xff08;1&#xff09;配置ip并禁用firewalld和s…

阿里云域名怎么綁定

阿里云服務器綁定域名全攻略&#xff1a;一步步輕松實現網站“零”障礙上線&#xff01; 域名&#xff0c;您網站在云端的“身份證”&#xff01; 在數字化浪潮中&#xff0c;擁有一個屬于自己的網站或應用&#xff0c;是個人展示、企業運營不可或缺的一環。而云服務器&#x…

從仿射矩陣得到旋轉量平移量縮放量

仿射變換原理 仿射變換是一種線性變換,可以包括平移、旋轉、縮放和剪切等操作。其一般公式可以表示為: $$\mathbf{x’} = A \mathbf{x} + \mathbf{b} ] 其中: (\mathbf{x}) 是輸入向量,通常表示一個點在二維或三維空間中的坐標。(\mathbf{x’}) 是輸出向量,表示經過仿射變…

C++課設:通訊錄管理系統(vector、map協作實現)

名人說:路漫漫其修遠兮,吾將上下而求索。—— 屈原《離騷》 創作者:Code_流蘇(CSDN)(一個喜歡古詩詞和編程的Coder??) 專欄介紹:《編程項目實戰》 目錄 一、為什么選擇C++開發通訊錄系統?1. C++的現狀2. STL標準模板庫的威力二、系統架構設計與STL容器選型1. 三層架構…

Spring Boot 常用注解面試題深度解析

&#x1f91f;致敬讀者 &#x1f7e9;感謝閱讀&#x1f7e6;笑口常開&#x1f7ea;生日快樂?早點睡覺 &#x1f4d8;博主相關 &#x1f7e7;博主信息&#x1f7e8;博客首頁&#x1f7eb;專欄推薦&#x1f7e5;活動信息 文章目錄 Spring Boot 常用注解面試題深度解析一、核心…

黃曉明新劇《潛淵》定檔 失憶三面間諜開啟諜戰新維度

據悉&#xff0c;黃曉明領銜主演的諜戰劇《潛淵》已于近日正式定檔6月9日&#xff0c;該劇以“失憶三面間諜”梁朔為核心&#xff0c;打破傳統諜戰劇的框架和固有角度&#xff0c;以一種特別的視角將懸疑感推向極致。劇中&#xff0c;梁朔因頭部受傷失去記憶&#xff0c;陷入身…

【自動駕駛避障開發】如何讓障礙物在 RViz 中‘顯形’?呈現感知數據轉 Polygon 全流程

【自動駕駛避障開發】如何讓障礙物在 RViz 中"顯形"?呈現感知數據轉 Polygon 全流程 自動駕駛系統中的障礙物可視化是開發調試過程中至關重要的一環。本文將詳細介紹如何將自動駕駛感知模塊檢測到的障礙物數據轉換為RViz可顯示的Polygon(多邊形)形式,實現障礙物…

#16 學習日志軟件測試

#16 #13布置的任務都沒有wanc 反思一下 一個是貪玩 一個是懶 還有一個原因是學習方式 單看視頻容易困 然后是一個進度寶貝 java ai 編程 完 挑著看的 廖雪峰教程 完 速看 很多過時 javaweb ai筆記 見到13.aop 小林coding 看到4.并發 java guide 還沒開始 若依框架 筆…

在Linux查看電腦的GPU型號

VGA 是指 Video Graphics Array&#xff0c;這是 IBM 于 1987 年推出的一種視頻顯示標準。 lspci | grep vga &#x1f4cc; lspci | grep -i vga 的含義 lspci&#xff1a;列出所有連接到 PCI 總線的設備。 grep -i vga&#xff1a;過濾輸出&#xff0c;僅顯示包含“VGA”字…

daz3d + PBRSkin (MDL)+ SSS

好的&#xff0c;我們來解釋一下 Daz3D 中的 PBRSkin (MDL) Shader。 簡單來說&#xff0c;PBRSkin (MDL) 是 Daz Studio 中一種基于物理渲染&#xff08;PBR&#xff09;技術、專門用于創建高度逼真人物皮膚效果的著色器&#xff08;Shader&#xff09;。 它利用 NVIDIA 的材…

會計 - 合并1- 業務、控制、合并日

一、業務 1.1 業務的定義以及構成要素 業務,是指企業內部某些生產經營活動或資產的組合,該組合一般具有投入、加工處理過程和產出能力,能夠獨立計算其成本費用或所產生的收入。 (1)投入,指原材料、人工、必要的生產技術等無形資產以及構成產出能力的機器設備等其他長期資…

uni-app 項目支持 vue 3.0 詳解及版本升級方案?

uni-app 支持 Vue 3.0 詳解及升級方案 一、uni-app 對 Vue 3.0 的支持現狀 uni-app 從 3.0 版本 開始支持 Vue 3.0&#xff0c;主要變化包括&#xff1a; 核心框架升級&#xff1a; 基于 Vue 3.0 的 Composition API 和 Options API 雙模式支持提供 vueuse/core 等組合式 API…

Java高級 | 【實驗三】Springboot 靜態資源訪問

隸屬文章&#xff1a; Java高級 | &#xff08;二十二&#xff09;Java常用類庫-CSDN博客 系列文章&#xff1a; Java高級 | 【實驗一】Spring Boot安裝及測試 最新-CSDN博客 Java高級 | 【實驗二】Springboot 控制器類相關注解知識-CSDN博客 目錄 一、Thymeleaf 1.1 是什么&…

12、企業應收賬款(AR)全流程解析:從發票開具到回款完成

在商業活動中&#xff0c;現金流如同企業的命脈&#xff0c;而應收管理則是維系這條命脈正常運轉的重要保障。許多企業由于對應收賬款缺乏有效管理&#xff0c;常常面臨資金周轉困難的問題。實踐證明&#xff0c;建立科學的應收管理體系能夠顯著提升資金回籠效率&#xff0c;為…

Python訓練營打卡Day46(2025.6.6)

知識點回顧&#xff1a; 不同CNN層的特征圖&#xff1a;不同通道的特征圖什么是注意力&#xff1a;注意力家族&#xff0c;類似于動物園&#xff0c;都是不同的模塊&#xff0c;好不好試了才知道。通道注意力&#xff1a;模型的定義和插入的位置通道注意力后的特征圖和熱力圖 i…

ASP.NET MVC添加視圖示例

ASP.NET MVC高效構建Web應用- 商品搜索 - 京東 視圖&#xff08;V&#xff09;是一個動態生成HTML頁面的模板&#xff0c;它負責通過用戶界面展示內容。本節將修改HelloWorldController類&#xff0c;并使用視圖模板文件&#xff0c;以干凈地封裝生成對客戶端的HTML響應的過程…

12.6Swing控件4 JSplitPane JTabbedPane

JSplitPane JSplitPane 是 Java Swing 中用于創建分隔面板的組件&#xff0c;支持兩個可調整大小組件的容器。它允許用戶通過拖動分隔條來調整兩個組件的相對大小&#xff0c;適合用于需要動態調整視圖比例的場景。 常用方法&#xff1a; setLeftComponent(Component comp)&a…

Spark 單機模式部署與啟動

&#x1f680; Spark 單機模式部署與啟動教程&#xff08;適配 Hadoop 3.1.1&#xff09; 本文記錄了在 Linux 環境中部署 Spark 的完整過程&#xff0c;使用 Standalone 單機模式&#xff0c;適配 Hadoop 3.1.1&#xff0c;最終可通過 Web 頁面訪問 Spark Master 狀態界面。 …

JAVA學習 DAY2 java程序運行、注意事項、轉義字符

本系列可作為JAVA學習系列的筆記&#xff0c;文中提到的一些練習的代碼&#xff0c;小編會將代碼復制下來&#xff0c;大家復制下來就可以練習了&#xff0c;方便大家學習。 點贊關注不迷路&#xff01;您的點贊、關注和收藏是對小編最大的支持和鼓勵&#xff01; 系列文章目錄…