Spring统一功能处理:拦截器、响应与异常的统一管理

news2024/9/25 9:33:02


目录

一.拦截器

二.统一数据返回格式

三.统一异常处理


一.拦截器

拦截器是Spring框架提供的核⼼功能之⼀,主要⽤来拦截⽤⼾的请求,在指定⽅法前后,根据业务需要执⾏预先设定的代码。

也就是说,允许开发⼈员提前预定义⼀些逻辑,在⽤⼾的请求响应前后执⾏,也可以在⽤⼾请求前阻⽌其执⾏。

在拦截器当中,开发⼈员可以在应⽤程序中做⼀些通⽤性的操作,⽐如通过拦截器来拦截前端发来的请求,判断Session中是否有登录⽤⼾的信息,如果有就可以放⾏,如果没有就进⾏拦截。

添加拦截器后,在原先逻辑之前会先判断是否拦截

使用拦截器需要分为俩步骤:

  • 自定义拦截器
  • 配置拦截器 

⾃定义拦截器:需实现HandlerInterceptor接⼝,并重写其⽅法

public interface HandlerInterceptor {
    //⽬标⽅法执⾏前执⾏,返回值表示是否拦截
    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }
    
    //⽬标⽅法执⾏后执⾏
    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }
    
    //视图渲染完毕后执⾏
    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    }
}
  1. preHandle()⽅法:⽬标⽅法执⾏前执⾏,返回true:继续执⾏后续操作;返回false:中断后续操作.
  2. postHandle()⽅法:⽬标⽅法执⾏后执⾏
  3. afterCompletion()⽅法:视图渲染完毕后执⾏,最后执⾏(但是现在基于前后端分离的设计模式,一般不需要后端返回视图,故而很少用)

添加拦截器后,执⾏Controller的⽅法之前,请求会先被拦截器拦截住执⾏ preHandle() ⽅法,这个⽅法需要返回⼀个布尔类型的值:如果返回true,就表⽰放⾏本次操作并且继续访问controller中的⽅法;如果返回false,则不会放⾏(controller中的⽅法也不会执⾏)。controller当中的⽅法执⾏完毕后,再回过来执⾏ postHandle() 这个⽅法以及afterCompletion() ⽅法,执⾏完毕之后,最终给浏览器响应数据。

@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("LoginInterceptor ⽬标⽅法执⾏前执⾏..");
        return true;
    }
    
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("LoginInterceptor ⽬标⽅法执⾏后执⾏");
    }
    
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("LoginInterceptor 视图渲染完毕后执⾏,最后执⾏");
    }
}

自定义完成拦截器后,我们还需要将其使用起来,也就是进行相关配置

首先是要实现WebMvcConfigurer接口,为了将我们刚才自定义的拦截器进行注册,我们需要一个拦截器对象,通过依赖注入的方式注入其中。InterceptorRegistry表示拦截器注册类,我们通过该类的addInterceptor方法将注入的拦截器对象提交并且注册,通过addPathPatterns方法配置我们需要拦截的路径

@Configuration
public class WebConfig implements WebMvcConfigurer {
    //⾃定义的拦截器对象
    @Autowired
    private LoginInterceptor loginInterceptor;
    
    public void addInterceptors(InterceptorRegistry registry) {
        //注册⾃定义拦截器对象
        registry.addInterceptor(loginInterceptor)
                .addPathPatterns("/**");//设置拦截器拦截的请求路径( /** 表⽰拦截所有请求)
    }
}

我们在注册配置拦截器的时候,通过 addPathPatterns() ⽅法指定要拦截哪些请求,也可以通过excludePathPatterns() 指定不拦截哪些请求。

@Configuration
public class WebConfig implements WebMvcConfigurer {
    //⾃定义的拦截器对象
    @Autowired
    private LoginInterceptor loginInterceptor;
    
    public void addInterceptors(InterceptorRegistry registry) {
        //注册自定义拦截器对象
        registry.addInterceptor(loginInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns("/user/login");
    }
}

对于拦截路径,有以下需要注意

拦截路径含义举例
/*一级路径能匹配/user,/book,/login,不能匹配 /user/login
/**任意级路径能匹配/user,/book,/login,/user/login

对于一些比较复杂比较多的路径,可以将其封装到一个集合中再统一导入,即下面俩者的效果是一样的。

@Configuration
public class WebConfig implements WebMvcConfigurer {
    //⾃定义的拦截器对象
    @Autowired
    private LoginInterceptor loginInterceptor;
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //注册⾃定义拦截器对象
        registry.addInterceptor(loginInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns("/user/login")
                .excludePathPatterns("/**/*.js") 
                .excludePathPatterns("/**/*.css")
                .excludePathPatterns("/**/*.png")
                .excludePathPatterns("/**/*.html");
    }
}
@Configuration
public class WebConfig implements WebMvcConfigurer {
    //⾃定义的拦截器对象
    @Autowired
    private LoginInterceptor loginInterceptor;
    private List<String> excludePaths = Arrays.asList(
            "/user/login",
            "/**/*.js",
            "/**/*.css",
            "/**/*.png",
            "/**/*.html"
    );
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //注册⾃定义拦截器对象
        registry.addInterceptor(loginInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns(excludePaths);
    }
}

二.统一数据返回格式

统⼀的数据返回格式使⽤ @ControllerAdvice 和 ResponseBodyAdvice 的⽅式实现,@ControllerAdvice 表⽰控制器通知类

添加类 ResponseAdvice,实现 ResponseBodyAdvice 接⼝,并在类上添加@ControllerAdvice 注解,示例如下:

@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return false;
    }
    
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        return null;
    }
}

supports⽅法:判断是否要执⾏beforeBodyWrite⽅法,true为执⾏,false不执⾏。通过该⽅法可以选择哪些类或哪些⽅法的response要进⾏处理,其他的不进⾏处理。

beforeBodyWrite⽅法:对response⽅法进⾏具体操作处理。


三.统一异常处理

统⼀异常处理使⽤的是 @ControllerAdvice + @ExceptionHandler 来实现的,@ControllerAdvice 表⽰控制器通知类,@ExceptionHandler 是异常处理器,两个结合表⽰当出现异常的时候执⾏某个通知,也就是执⾏某个⽅法事件。

示例代码如下:

@ControllerAdvice
public class ErrorAdvice {
    @ExceptionHandler
    public Object handler(Exception e) {
        return Result.fail(e.getMessage());
    }
}

以上代码表⽰,如果代码出现Exception异常(包括Exception的⼦类),就返回⼀个 Result的对象。

我们可以针对不同的异常,返回不同的结果。

@ControllerAdvice
public class ErrorAdvice {
    @ExceptionHandler
    public Object handler(Exception e) {
        return Result.fail(e.getMessage());
    }
    
    @ExceptionHandler
    public Object handler(NullPointerException e) {
        return Result.fail("发⽣NullPointerException:"+e.getMessage());
    }
    
    @ExceptionHandler
    public Object handler(ArithmeticException e) {
        return Result.fail("发⽣ArithmeticException:"+e.getMessage());
    }
}

当有多个异常通知时,匹配顺序为当前类及其⼦类向上依次匹配。




 本次的分享就到此为止了,希望我的分享能给您带来帮助,创作不易也欢迎大家三连支持,你们的点赞就是博主更新最大的动力!如有不同意见,欢迎评论区积极讨论交流,让我们一起学习进步!有相关问题也可以私信博主,评论区和私信都会认真查看的,我们下次再见

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1981504.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

全球情境感知计算市场规划预测:未来六年CAGR为17.0%

随着全球数字化转型的加速和物联网技术的广泛应用&#xff0c;情境感知计算作为一种能够理解和响应环境变化的智能技术&#xff0c;正逐渐受到更多关注。本文旨在通过深度分析情境感知计算行业的各个维度&#xff0c;揭示行业发展趋势和潜在机会。 【市场趋势的演变】 1. 市场…

C++——string类及其使用

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件iostream的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;Yan. yan.                        …

体系结构论文导读(三十一)(上):Soft errors in DNN accelerators: A comprehensive review

Soft errors in DNN accelerators: A comprehensive review DNN 加速器中的软错误&#xff1a;全面回顾 一、文章核心 深度学习任务覆盖了广泛应用。DNN算法被实现于不同系统上&#xff0c;从小型嵌入式设备到数据中心。DNN加速器&#xff08;例如GPU、FPGA、ASIC&#xff0…

JetBrains:Wrong tag。注释告警

报错信息如下&#xff1a; Wrong tag ‘copyright:’ &#xff0c;这个是alt enter 选择 Add copyright:to custom tags&#xff0c;虽然能解决问题&#xff0c;如果创建一个新项目又回出现这个告警提示。 其实这个问题的就是这个在Java Doc里面不存在&#xff0c;才会出现这…

Bugku-CTF-聪明的php

pass a parameter and maybe the flag files filename is random :> 传递一个参数&#xff0c;可能标记文件的文件名是随机的: 于是传一下参&#xff0c;在原网页后面加上/?a1,发现网页出现了变化 3.传入参数&#xff0c;一般情况下是文件包含&#xff0c;或者命令执行&…

linux安装weblogic

文章目录 weblogic是干什么用的weblogic安装前置条件1. 安装jdk2.安装weblogic2.1.创建用户组及用户2.2.切换用户上传安装jar包到目录下&#xff0c;配置文件进行安装准备配置文件2.3保证安装配置文件和安装jar包在同一目录&#xff0c;执行安装命令 3. 创建域来启动页面3.1 构…

Science Robotics 封面论文:美国宇航局喷气推进实验室开发了自主蛇形机器人,用于冰雪世界探索

人们对探索冰冷的卫星&#xff08;如土卫二&#xff09;的兴趣越来越大&#xff0c;这可能具有天体生物学意义。然而&#xff0c;由于地表或冰口内的环境极端&#xff0c;获取样本具有挑战性。美国宇航局的喷气推进实验室正在开发一种名为Exobiology Extant Life Surveyor&…

【分巧克力】

题目 代码 #include<bits/stdc.h> using namespace std;const int N 1e510; int n, k; int h[N], w[N]; bool check(int mid) {int cnt 0;for(int i 1; i < n; i){cnt (h[i] / mid) * (w[i] / mid); //切块一定是切出长方形洞才最省料&#xff0c;这样的话能切几…

等保测评练习卷27

等级保护初级测评师试题27 姓名&#xff1a; 成绩&#xff1a; 一、判断题&#xff08;10110分&#xff09; 1.对于大型物联网来说&#xff0c;处理应用层一般由云计算平台和业务应用终端设备构成。&#xff08; T &#xff09; …

企业数据接口:股权穿透

支持查询公司名称&#xff0c;股权路径&#xff0c;股东出资比例&#xff0c;层级等信息&#xff0c;呈现出公司多层次股权结构&#xff0c;高效理清企业投资股权关系

部署服务器项目及发布

当技术总监直接丢给我一个服务器账号密码时&#xff0c;我该怎么完成映射本机&#xff1b;配置网关&#xff1b;配置代理和发布项目呢&#xff1f; 我使用的是putty远程登录到服务器 输入ip后&#xff0c;点open 输入账号密码 登录的账号如果不是root&#xff1b;使用sudo su…

表中记录的操作

一、查询表中的记录 二、在表中插入记录&#xff0c;删除记录&#xff0c;修改记录 三、常用的运算符 四、数据类型

string.format()拼接参数

string.format()拼接参数 private static void testString() {String queryParams String.format("?pwdErrNum%s&userSts%s&lockSts%s", 123, 1, 1);System.out.println(queryParams);}打印结果

事务的原理(学习笔记)

redo log 如果没有redo log 我们在执行完增删改查语句后会将脏页直接刷新到磁盘中&#xff0c;此时用户事务已经提交&#xff0c;一旦刷新失败则无法修复数据。如果不适用redo log 还会存在性能问题&#xff0c;事务中的一组操作都是随机操作数据页&#xff0c;涉及到大量随机…

DeepSeek Coder V2开源发布,首超GPT4-Turbo的代码能力

击败GPT4-Turbo&#xff0c;最强开源代码模型DeepSeek-Coder-V2问世&#xff5c;SiliconCloud上新 6月17日&#xff0c;深度求索正式开源了DeepSeek-Coder-V2模型。 根据相关评测榜单&#xff0c;这是全球首个在代码、数学能力上超越GPT-4-Turbo、Claude3-Opus、Gemini-1.5Pro…

DolphinDB 编程进阶:掌握这十个细节,让你的代码更出色

众所周知&#xff0c;编程细节不仅关乎代码的美观与整洁&#xff0c;更是确保软件质量、提升开发效率、减少维护成本以及保障系统稳定性的基石。 今天和大家分享的内容是&#xff1a;使用 DolphinDB 编程时&#xff0c;十个常被忽略但至关重要的细节。本文涵盖了元编程技巧、数…

攻防演练号角吹响,聚铭铭察高级威胁检测系统助您零失分打赢重保攻坚战

在数字化浪潮中&#xff0c;攻防演练成为了衡量网络安全防御力的核心标尺&#xff0c;其重要性与日俱增。这项由政府、行业监管或企业内部主导的安全活动&#xff0c;随着互联网普及而兴起&#xff0c;现已发展成为全球公认的检验网络安全体系效能的标准。它不仅关乎技术实力的…

JaCoCo - Java Code Coverage Library

概述 JaCoCo&#xff08;Java Code Coverage&#xff09;是一个开源的Java代码覆盖率库。它可以帮助开发人员测量单元测试和集成测试中代码的覆盖情况。通过使用JaCoCo&#xff0c;开发人员可以识别哪些代码没有被测试覆盖&#xff0c;从而提高代码的质量和可靠性。 功能 1.…

C语言宠物系统

功能有增加宠物信息&#xff0c;显示宠物信息&#xff0c;删除宠物信息&#xff0c;修改功能和排序功能&#xff0c;可以选择姓名排序&#xff0c;年龄排序&#xff0c;价格排序。进阶的功能有文件操作&#xff0c;动态内存开辟。。 test.c源文件 #include "Pet.h"v…

角色管理功能助你打造精准智慧校园系统

在智慧校园的信息化架构中&#xff0c;角色管理功能犹如一把精细的钥匙&#xff0c;开启着系统安全与高效运作的大门。它不仅关乎信息的访问权限&#xff0c;更深层次地影响着校园内各类活动的顺畅进行。 智慧校园的角色管理&#xff0c;首先体现在对用户群体的细致划分上。系统…