SpringBoot 统一功能处理
在我们写SpringBoot项目的时候,有些功能模块几乎每个项目都是一样,这些功能模块有:
1.统一用户登录权限验证;
2.统一数据格式返回;
3.统一异常处理;
统一用户登录权限验证
在我们利用Spring AOP来做统一登录验证的时候会遇到两个问题:
1.没有办法获取到HTTPSession对象;
2.很难做到只对某一部分拦截,对某一部分不拦截;
Spring拦截器
对于上面的问题可以使用Spring拦截器来解决,Spring拦截器HandlerInterceptor的实现分为一下两个步骤:
1. 创建自定义拦截器(判断用户是否登陆):该拦截器必须实现HandlerInterceptor并重写preHandle(执行具体方法之前的预处理)方法。
/*
* 登录拦截器
* */
public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception {HttpSession session = request.getSession(false);if(session!=null&&session.getAttribute("userinfo")!=null){//说明已经登录return true;}response.setStatus(401);return false;}
}
2.配置拦截器和拦截规则
/*
* 全局配置文件
* */
@Configuration
public class AppConfig implements WebMvcConfigurer {//配置拦截器和拦截规则@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**")//拦截所有请求.excludePathPatterns("/**/*.html")//排除所有的html文件.excludePathPatterns("/**/*.css")//排除所有的css文件.excludePathPatterns("/**/*.js")//排除所有的js文件.excludePathPatterns("/user/login");//排除登录接口}
}
结果:
因为拦截了.jpg文件,随意页面中的图片加载不出来,下面是我排除.jpg文件的接口以后的效果:
下面看一个具体的用户登录权限验证的操作:
首先用户是通过输入网址到达某个页面,这个页面可能是系统内部的某个页面(不是登录页面),这个时候因为没有登陆,所以就不能访问:
一:创建两个前端页面
- index.html
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<body>
<h1> index 页面</h1>
</body>
</html>
- login.html
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<body>
<h1>登录页面</h1>
</body>
</html>
二:写一个拦截器,拦截index页面,不拦截login页面
public class LoginIntercept implements HandlerInterceptor {/** 返回true表示拦截判断通过,可以访问后面的接口* 如果返回false表示拦截未通过,直接返回结果给前端* */@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//1.得到HttpSession对象HttpSession session = request.getSession(false);if(session!=null&&session.getAttribute("userinfo")!=null){//表示已经登录return true;}//执行到此行代码表示未登录,未登录就跳转到登录页面return false;}
}
@Configuration
public class AppConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginIntercept()).addPathPatterns("/**")//拦截所有的url.excludePathPatterns("/user/login")//不拦截登录接口.excludePathPatterns("/user/reg")//不拦截注册接口.excludePathPatterns("/login.html")//不拦截登录页面.excludePathPatterns("/reg.html")//不拦截注册页面.excludePathPatterns("/**/*.js")//不拦截所有的js信息.excludePathPatterns("/**/*.css")//不拦截所有的css信息.excludePathPatterns("/**/*.jpg");//不拦截所有的图片信息}
}
三:验证
四:让未登录的用户跳转到登录页面
输入http://localhost:8080/index.html以后因为没有登陆,它会自动的跳转到登录页面:
五:在url中输入session信息(输入以后相当于就登录了)
没有输入session信息之前的状态(访问):
我在浏览器输入框中输入localhost:8080/user/index,如果是登录状态,它就会显示Hello,index,但是现在我是未登录状态(也就是浏览器中没有我的登录信息——session) ,因为之前重定向到了登录页面,所以它会让我先登录:
在这个页面中,会让我输入登录信息,验证通过后浏览器就会自动的保存我的session,然后我就可以访问其他页面了 ,下面是我没有输入正确session的状态:
下面是我输入正确session之后的状态:
然后我在访问其他页面:
当我的登录信息正确以后,拦截器就不拦了,上面整个过程就是用户统一登录的验证。
Spring拦截器的原理
之前我们没有设置拦截器的时候,用户请求数据的流程是下面这样的:
添加拦截器以后,用户请求数据的流程:
也就是说在我们请求数据的时候,所有的请求否要通过拦截器这个关卡,如果拦截器返回false,请求就不能通过,返回true才能访问到要访问的数据。
关于统一访问前缀的添加
在我们使用拦截器拦截目标文件的时候,可以在相应的url地址前面加上前缀:
@Overridepublic void configurePathMatch(PathMatchConfigurer configurer) {//在所有的请求地址前面加上api前缀configurer.addPathPrefix("api",c->true);}
代码里面的c表示所有的controller
例如:在所有的请求地址前面加上api前缀
没加之前:
加了之后:
统一的异常处理
在我们写程序的时候,难免会遇到异常,这个异常可能是我们自己导致的也有可能是用户提交的数据导致的,虽然异常还可以try-catch一下处理一下,但是异常多了以后不可能每一个地方都去处理,而且在Spring事务中try-catch会导致事务不能回滚。为了解决这一普遍现象造成的问题,这里就可以Spring里面用统一异常处理机制来处理。
统一异常处理机制:
1.给异常处理类加上@controllerAdervice注解或者@RestControllerAdervice注解,@controllerAdervice注解这个注解表示控制器通知类,而@RestControllerAdervice是一个组合注解,它相当于@controllerAdervice+@ResponseBody,使用了这个注解以后,可以不再类上面加@ResponseBody注解。
@RestControllerAdvice//当前针对controller的通知类
public class MyExceptionAdervice {}
2.在方法上面加上@ExceptionHandler(XXX.class),添加异常返回的业务逻辑。
在controller里面写一个错误逻辑:
执行结果:
返回统一的数据格式
返回统一数据格式的好处:
- 方便前端程序员更好的接收和解析后端端口返回的数据;
- 有利于项目统一数据的维护和修改;
- 能够降低前后端程序员之间的沟通成本;
返回统一数据格式的实现也是分为两步:
1.在返回统一数据格式的类上面加上@ControllerAdvice注解;
2.让这个类实现ResponseBodyAdvice接口,并重写它里面的两个方法
@ControllerAdvice
public class MyResponseAdvice implements ResponseBodyAdvice {/** 返回一个boolean值,true表示返回数据之前对数据进行重写,也就是会进入beforeBodyWrite方法,再返回* 如果返回false表示对结果不进行任何处理,直接返回* */@Overridepublic boolean supports(MethodParameter returnType, Class converterType) {return true;}@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {HashMap<String,Object> result = new HashMap<>();result.put("state",1);result.put("data",body);result.put("msg","");return result;}
}
结果:
SpringBoot 统一功能处理相关推荐
- 一文带你看懂Springboot核心功能及优缺点
点击上方[视学算法]→右上角[...]→[设为星标⭐] SpringBoot核心功能 1.独立运行Spring项目 Spring boot 可以以jar包形式独立运行,运行一个Spring Boot项 ...
- springboot统一异常处理类及注解参数为数组的写法
springboot统一异常处理类及注解参数为数组的写法 参考文章: (1)springboot统一异常处理类及注解参数为数组的写法 (2)https://www.cnblogs.com/zhucww ...
- springboot统一异常处理及返回数据的处理
springboot统一异常处理及返回数据的处理 参考文章: (1)springboot统一异常处理及返回数据的处理 (2)https://www.cnblogs.com/renshengruozhi ...
- Spring Boot 统一功能处理
Spring Boot 统一功能处理 一.使用 Spring 拦截器来实现登录验证 引入 代码实现 步骤1 自定义拦截器 步骤2 添加拦截器并设置拦截规则 拦截规则 步骤3 创建前后端交互,用于测试 ...
- SpringBoot统一返回处理出现cannot be cast to java.lang.String异常
SpringBoot统一返回处理出现cannot be cast to java.lang.String异常 一 问题出现背景: 二 解决方案 三 异常原因分析 原因: 源码详细分析: 正常返回: 返 ...
- SpringBoot一站式功能提供框架(一)整合MybatisPlus、整合Swagger Knif4j、整合Druid多数据源--柚子真好吃
SpringBoot一站式功能提供框架(一)整合MybatisPlus.整合Swagger Knif4j.整合Druid多数据源--柚子真好吃 一.前言 二.功能描述 三.具体实现 四.开源地址 一. ...
- Spring Boot 统一功能处理(用户登录权限效验-拦截器、异常处理、数据格式返回)
文章目录 1. 统一用户登录权限效验 1.1 最初用户登录权限效验 1.2 Spring AOP 统一用户登录验证 1.3 Spring 拦截器 1.4 练习:登录拦截器 1.5 拦截器实现原理 1. ...
- Java开发面试题及答案,SpringBoot统一日志处理原理
<artifactId>slf4j-api</artifactId> <version>1.7.28</version> ``` 按照slf4j官方的说 ...
- SpringBoot - 统一格式封装及高阶全局异常处理
文章目录 Pre 演进过程 版本V1 版本2 Step1 约定统一返回格式 Step2 开发统一返回对象 Step3 约定接口状态码 Step4 验证 Step5 完善全局异常处理 @RestCont ...
最新文章
- vue拖拽控件生成界面代码_Blue HMI人机界面开发平台
- 前端学习(1954)vue之电商管理系统电商系统之重置表单数据
- HDU1284——钱币兑换问题【dp】
- xshell 5连接NAT模式的虚拟机
- matlab画圆函数
- mix2线刷开发板救砖_小米MIX2线刷刷机教程_小米MIX2第三方rom包_线刷救砖教程
- DRM之Widevine学习入门
- html网页制作代码大全表白 html表白代码大全可复制,浪漫的html表白特效网页制作源代码
- Python鸡兔同笼
- java写文件描述_详解Java中的File文件类以及FileDescriptor文件描述类
- java学生成绩分90及格_Java基础练习:题目:利用条件运算符的嵌套来完成此题:学习成绩=90分的同学用A表示,60-89分之间的用B表示,60分以下 的用C表示。 - 菜鸟头头...
- 安全加密邮箱哪个好?
- MATLAB程序设计与应用刘卫国(第三版)课后实验答案——12
- 洛谷 P1646 [国家集训队]happiness 网络流 最小割 Dinic+当前弧优化
- python中心性评价_centrality 计算复杂网络中的节点或边 数中心性,基于python的 工具箱 matlab 238万源代码下载- www.pudn.com...
- 贪心算法——1225:金银岛
- 龙芯软件开发(10)--龙芯2E指令
- leetcode 561
- SQL中内部表和外部表的区别
- ASP.Net Core 2.2 MVC入门到基本使用系列 (四)