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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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; 系列文章目录…