在我们写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 统一功能处理相关推荐

  1. 一文带你看懂Springboot核心功能及优缺点

    点击上方[视学算法]→右上角[...]→[设为星标⭐] SpringBoot核心功能 1.独立运行Spring项目 Spring boot 可以以jar包形式独立运行,运行一个Spring Boot项 ...

  2. springboot统一异常处理类及注解参数为数组的写法

    springboot统一异常处理类及注解参数为数组的写法 参考文章: (1)springboot统一异常处理类及注解参数为数组的写法 (2)https://www.cnblogs.com/zhucww ...

  3. springboot统一异常处理及返回数据的处理

    springboot统一异常处理及返回数据的处理 参考文章: (1)springboot统一异常处理及返回数据的处理 (2)https://www.cnblogs.com/renshengruozhi ...

  4. Spring Boot 统一功能处理

    Spring Boot 统一功能处理 一.使用 Spring 拦截器来实现登录验证 引入 代码实现 步骤1 自定义拦截器 步骤2 添加拦截器并设置拦截规则 拦截规则 步骤3 创建前后端交互,用于测试 ...

  5. SpringBoot统一返回处理出现cannot be cast to java.lang.String异常

    SpringBoot统一返回处理出现cannot be cast to java.lang.String异常 一 问题出现背景: 二 解决方案 三 异常原因分析 原因: 源码详细分析: 正常返回: 返 ...

  6. SpringBoot一站式功能提供框架(一)整合MybatisPlus、整合Swagger Knif4j、整合Druid多数据源--柚子真好吃

    SpringBoot一站式功能提供框架(一)整合MybatisPlus.整合Swagger Knif4j.整合Druid多数据源--柚子真好吃 一.前言 二.功能描述 三.具体实现 四.开源地址 一. ...

  7. Spring Boot 统一功能处理(用户登录权限效验-拦截器、异常处理、数据格式返回)

    文章目录 1. 统一用户登录权限效验 1.1 最初用户登录权限效验 1.2 Spring AOP 统一用户登录验证 1.3 Spring 拦截器 1.4 练习:登录拦截器 1.5 拦截器实现原理 1. ...

  8. Java开发面试题及答案,SpringBoot统一日志处理原理

    <artifactId>slf4j-api</artifactId> <version>1.7.28</version> ``` 按照slf4j官方的说 ...

  9. SpringBoot - 统一格式封装及高阶全局异常处理

    文章目录 Pre 演进过程 版本V1 版本2 Step1 约定统一返回格式 Step2 开发统一返回对象 Step3 约定接口状态码 Step4 验证 Step5 完善全局异常处理 @RestCont ...

最新文章

  1. vue拖拽控件生成界面代码_Blue HMI人机界面开发平台
  2. 前端学习(1954)vue之电商管理系统电商系统之重置表单数据
  3. HDU1284——钱币兑换问题【dp】
  4. xshell 5连接NAT模式的虚拟机
  5. matlab画圆函数
  6. mix2线刷开发板救砖_小米MIX2线刷刷机教程_小米MIX2第三方rom包_线刷救砖教程
  7. DRM之Widevine学习入门
  8. html网页制作代码大全表白 html表白代码大全可复制,浪漫的html表白特效网页制作源代码
  9. Python鸡兔同笼
  10. java写文件描述_详解Java中的File文件类以及FileDescriptor文件描述类
  11. java学生成绩分90及格_Java基础练习:题目:利用条件运算符的嵌套来完成此题:学习成绩=90分的同学用A表示,60-89分之间的用B表示,60分以下 的用C表示。 - 菜鸟头头...
  12. 安全加密邮箱哪个好?
  13. MATLAB程序设计与应用刘卫国(第三版)课后实验答案——12
  14. 洛谷 P1646 [国家集训队]happiness 网络流 最小割 Dinic+当前弧优化
  15. python中心性评价_centrality 计算复杂网络中的节点或边 数中心性,基于python的 工具箱 matlab 238万源代码下载- www.pudn.com...
  16. 贪心算法——1225:金银岛
  17. 龙芯软件开发(10)--龙芯2E指令
  18. leetcode 561
  19. SQL中内部表和外部表的区别
  20. ASP.Net Core 2.2 MVC入门到基本使用系列 (四)

热门文章

  1. 数据结构----主席树
  2. REASONING ABOUT ENTAILMENT WITH NEURAL ATTENTION 论文阅读笔记
  3. HTTP取消SSL认证
  4. echarts 桑基图 添加标志线问题
  5. 23模式--建造者模式
  6. coalesce函数的用法
  7. android 主流机型排行,安卓手机性能排行:华为Mate40 Pro仅排第四,第一名无可撼动...
  8. 往哪里看低买高卖和利润之间
  9. R语言-神经网络包RSNNS
  10. Jetson TX1 /TX2 对比介绍