当前位置: 首页 > news >正文

Spring统一功能处理

1. AOP存在的问题

  • 获取参数复杂
  • AOP的规则相对简单

2. 拦截器

2.1. 应用(以登录为例)

2.1.1. 自定义拦截器

新建interceptor文件夹

import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;@Component
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("username")!=null){//通过return true;}else {//没登录response.setStatus(401);return false;}}
}

2.1.2. 将自定义拦截器加入到系统配置

新建config文件夹

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import springaop.interceptor.LoginInterceptor;@Configuration
public class AppConfig implements WebMvcConfigurer {@Autowiredprivate LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginInterceptor).addPathPatterns("/**")         //"/**"表示拦截所有.excludePathPatterns("/user/login")  //除了登录.excludePathPatterns("/user/reg");    //除了注册}
}

2.1.3. 业务代码

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;@Slf4j
@RequestMapping("/user")
@RestController
public class UserController {//获取用户信息@RequestMapping("/getInfo")public String getInfo(){log.info("log.getInfo");return "get info...";}//注册@RequestMapping("/reg")public String reg(){log.info("log.reg");return "reg...";}//登录@RequestMapping("/login")public boolean login(HttpServletRequest request,String username,String password){log.info("log.login");//判断username和password是否为空
//        if (username!=null && username.equals("") && password!=null && password.equals("")){
//            //
//        }if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)){return false;}if (!"admin".equals(username) || !"admin".equals(password)){return false;}HttpSession session = request.getSession(true);session.setAttribute("username",username);return true;}
}

2.2. 排除所有静态资源方法

方法1

registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**") // 拦截所有接口.excludePathPatterns("/**/*.js").excludePathPatterns("/**/*.css").excludePathPatterns("/**/*.jpg").excludePathPatterns("/login.html").excludePathPatterns("/**/login"); // 排除接口

方法2

private final List<String> excludePaths = //注意List的这种方式的初始化赋值不允许再追加元素Arrays.asList("/**/*.html","blog-editormd","/css/**","/js/**","/pic/**","/user/login","/user/res");@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginInterceptor).addPathPatterns("/**").excludePathPatterns(excludePaths);}

2.3. 实现原理

2.3.1. 总体思路

2.3.2. 部分源码分析

拦截器是基于AOP实现的

(AOP基于动态代理(JDK|CGLIB))

3. 统一功能处理

3.1. 统一登录处理

参考上一节 拦截器的应用

3.2. 统一异常处理

对于下面的异常, 我们在访问页面的时候,不希望让用户看到

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/exception")
public class ExceptionController {//算数异常@RequestMapping("/test1")public boolean test1(){int a = 10/0;return true;}//空指针异常@RequestMapping("/test2")public boolean test2(){String str = null;System.out.println(str.length());return true;}//手动异常@RequestMapping("/test3")public boolean test3(){throw new RuntimeException("手动异常");}
}

可能出现的问题:

类上面的@RequestMapping("/ex")访问的时候会有未知的问题,改成@RequestMapping("/exception")比较好

3.2.1. 配置ErrorHandler

针对不同的异常,进行不同的操作

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;import java.util.HashMap;@Slf4j
@ControllerAdvice
@ResponseBody
public class ErrorHandler {@ExceptionHandlerpublic Object error(Exception e){HashMap<String,Object> result = new HashMap<>();log.info("内部异常:",e);result.put("success",0);result.put("code",-1);result.put("msg","内部异常");return result;}@ExceptionHandlerpublic Object error(ArithmeticException e){HashMap<String,Object> result = new HashMap<>();log.info("算数异常:",e);result.put("success",0);result.put("code",-2);result.put("msg","算术异常");return result;}@ExceptionHandlerpublic Object error(NullPointerException e){HashMap<String,Object> result = new HashMap<>();log.info("空指针异常:",e);result.put("success",0);result.put("code",-3);result.put("msg","空指针异常");return result;}
}

3.2.1.1. 可能会遇到的问题

①写完代码访问的时候,会是错误404, 而且异常是返回的不是一个视图, 需要添加@ResponseBody注解,让程序意识到返回的就是数据, 而不是视图

②分辨不出来异常

之前在切面的@Around环绕通知里有一段代码

要是遇到了异常都会抛出RuntimeException, 从而掩盖了真正的异常, 需要改成下面的样子, 抛出真正的异常

3.3. 统一数据返回格式

3.3.1. 好处

统一数据返回格式的优点有很多. 比如以下几个:

  • 方便前端程序员更好的接收和解析后端数据接口返回的数据
  • 降低前端程序员和后端程序员的沟通成本,按照某个格式实现就行了,因为所有接口都是这样返回的
  • 有利于项目统一数据的维护和修改
  • 有利于后端技术部门的统一规范的标准制定,不会出现稀奇古怪的返回内容

3.3.2. 代码

新建ResponseHandler

import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;import java.util.HashMap;@ControllerAdvice
public class ResponseHandler implements ResponseBodyAdvice {@Overridepublic boolean supports(MethodParameter returnType, Class converterType) {return true;    //一定要改成true}@SneakyThrows@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {HashMap<String,Object> result = new HashMap<>();result.put("success",1);result.put("data",body);result.put("errMsg","");//对字符串进行特殊处理if (body instanceof String){ObjectMapper mapper = new ObjectMapper();return mapper.writeValueAsString(result);}return result;}
}

添加这段代码之前, 访问成功了,得到的是true, 加上这段代码就变成了{"data":true,"success":1,"errMsg":""}

3.3.2.1. 可能出现的问题

①supports()的返回值一定要改成true

②getInfo()的业务代码的返回值是String, 会引发java.util.HashMap cannot be cast to java.lang.String错误. 由于内部的数据类型转换问题导致, 解决方法是加一步验证.

这段代码会有异常, 用@SneakyThrows处理. 这个注解的作用就是自动生成一个try-catch, 直接抛出异常

相关文章:

Spring统一功能处理

1. AOP存在的问题 获取参数复杂AOP的规则相对简单 2. 拦截器 2.1. 应用(以登录为例) 2.1.1. 自定义拦截器 新建interceptor文件夹 import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest; import javax.servlet.http…...

搭建CFimagehost私人图床,实现公网远程访问的详细指南

文章目录 1.前言2. CFImagehost网站搭建2.1 CFImagehost下载和安装2.2 CFImagehost网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1 Cpolar临时数据隧道3.2 Cpolar稳定隧道&#xff08;云端设置&#xff09;3.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 4.公网访问测…...

Python的logging.config模块

要使用Python的logging.config模块记录一个月的日志数据&#xff0c;你可以按照以下步骤进行操作&#xff1a; 首先&#xff0c;导入必要的模块&#xff1a; import logging import logging.config import datetime创建一个配置文件&#xff0c;例如logging.ini&#xff0c;用…...

【2023】LeetCode HOT 100——滑动窗口子串

目录 1. 无重复字符的最长子串1.1 C++实现1.2 Python实现1.3 时空分析2. 找到字符串中所有字母异位词2.1 C++实现2.2 Python实现2.3 时空分析3. 和为 K 的子数组3.1 C++实现3.2 Python实现3.3 时空分析4. 滑动窗口最大值4.1 C++实现4.2 Python实现4.3 时空分析5. 最小覆盖子串5…...

【云卓笔记】mavlink java文件

根据飞控提供的xml文件来生成的 生成的就是这样的java文件 准备工作: Mavlink协议生成 参考 1.安装mavlink : 使用MAVLink工具的要求是 Python 3.3 (recommended) or Python 2.7 Python future模块 (可选) PythonTklnter模块(如果需要使用图形用户界面)。 环境变量PYTHO…...

电机控制软件框架

应用层包括main 主函数模块&#xff0c;ISR 中断处理函数模块、时基Systick 模块和BLDC 应用接口模块&#xff1b;算法层包括BLDC Algorithm 模块和PID control 模块&#xff1b;驱动层&#xff08;Driver layer&#xff09;&#xff1a;包括GD32Fxx_Standard_peripheral libra…...

SCCB与IIC的异同及FPGA实现的注意事项

文章目录 前言一、信号线二、SCCB数据传输格式三、SCCB写&#xff08;与IIC完全一致&#xff09;四、SCCB读五、SCCB和IIC的区别 前言 IIC接口有比较广泛的应用&#xff0c;而SCCB&#xff08;Serial Camera Control Bus&#xff0c;串行摄像头控制总线&#xff09;是由OV&…...

【开发】安防监控视频智能分析平台新功能:安全帽/反光衣/安全带AI识别详解

人工智能技术已经越来越多地融入到视频监控领域中&#xff0c;近期我们也发布了基于AI智能视频云存储/安防监控视频AI智能分析平台的众多新功能&#xff0c;该平台内置多种AI算法&#xff0c;可对实时视频中的人脸、人体、物体等进行检测、跟踪与抓拍&#xff0c;支持口罩佩戴检…...

数据结构 - 线性表的顺序存储

一、顺序存储定义&#xff1a; 把逻辑上相邻的数据元素存储在物理上相邻的存储单元中。简言之&#xff0c;逻辑上相邻&#xff0c;物理上也相邻顺序表中&#xff0c;任一元素可以随机存取&#xff08;优点&#xff09; 二、顺序表中元素存储位置的计算 三、顺序表在算法中的实…...

栈和队列在数据结构中的应用

文章目录 理解栈和队列的概念及其特点栈的应用和操作队列的应用和操作结论 &#x1f389;欢迎来到数据结构学习专栏~探索栈和队列在数据结构中的应用 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&#xff1a;IT陈寒的博客&#x1f388;该系列文章专栏&#xff1a;…...

AndroidStudio升级后总是Read Time Out的解决办法

AndroidStudio升级后在gradle的时候总是Time out&#xff0c;遇到过多次&#xff0c;总结一下解决办法 1、gradle下载超时 在工程目录../gradle/wrapper/gradle-wrapper.properties中找到gradle版本的下载链接&#xff0c;如下图&#xff1a; 将其复制到迅雷里下载&#xff0…...

升级Go 版本到 1.19及以上,Goland: file.Close() 报错: Unresolved reference ‘Close‘

错误截图 解决方法 File -> Settings -> Go -> Build Tags & Vendoring -> Custom tags -> 添加值 “unix” 原因 Go 1.19 引入了unix构建标签。因此&#xff0c;需要添加unix到自定义标签。 参考 https://blog.csdn.net/weixin_43940592/article/det…...

进程,线程,协程

1、进程 进程是具有一定独立功能的程序关于某个​​数据集​​合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。每个进程都有自己的独立内存空间&#xff0c;不同进程通过进程间通信来通信。由于进程比较重量&#xff0c;占据独立的内存&#xff0c;所以上下…...

车联网技术介绍

上图是目前车联网架构图&#xff0c;基于“云-管-端”的车联网系统架构以支持车联网应用的实现&#xff0c; “云”是指 V2X 基础平台、高基于精度定位平台等基础能力&#xff0c;可实现车辆动态厘米级定位&#xff0c;这将满足现阶段以及未来车联网应用场景的定位精度需求。 “…...

并发-线程池

阻塞队列 笔记地址 点击进入 队列&#xff1a;先进先出 限定在一端进行插入&#xff0c;一端进行删除 出队为队头&#xff0c;入队为队尾 阻塞队列 BlockingQueue Queue接口继承Collection接口添加元素&#xff1a;add()&#xff0c;队列满了对抛出异常offer()&#xff0c;队…...

openCV实战-系列教程5:边缘检测(Canny边缘检测/高斯滤波器/Sobel算子/非极大值抑制/线性插值法/梯度方向/双阈值检测 )、原理解析、源码解读

打印一个图片可以做出一个函数&#xff1a; def cv_show(img,name):cv2.imshow(name,img)cv2.waitKey()cv2.destroyAllWindows() 1、Canny边缘检测流程 Canny是一个科学家在1986年写了一篇论文&#xff0c;所以用自己的名字来命名这个检测算法&#xff0c;Canny边缘检测算法…...

【数据仓库】Linux、CentOS源码安装Superset

Linux、CentOS源码安装Superset步骤&#xff0c;遇到的各种问题。 报错问题&#xff1a; Linux下pip版本问题 You are using pip version 8.1.2, however version 22.2.2 is available. 解决办法&#xff1a; 安装python3的pip yum install python3-pip再升级 pip3 install…...

高并发网站的负载均衡设计

大型高并发网站的负载均衡设计通常包含以下方面: 1. 硬件负载均衡器 在入口使用专业的硬件F5等负载均衡器,实现流量分发,并承担第一层保护。 2. DNS轮询/一致性哈希 结合DNS,使用轮询或一致性哈希方式将请求分散到后端不同的真实服务器。 3. CDN负载均衡 针对静态资源,使用C…...

Unity C# 之 Task、async和 await 、Thread 基础使用的Task的简单整理

Unity C# 之 Task、async和 await 、Thread 基础使用的Task的简单整理 目录 Unity C# 之 Task、async和 await 、Thread 基础使用的Task的简单整理 一、Task、async和 await 、Thread 基础概念 1、线程&#xff0c;多线程 2、Task 3、async &#xff08;await &#xff09;…...

介绍 Docker 的基本概念和优势,以及在应用程序开发中的实际应用。

Docker是一个开放源代码的容器化平台&#xff0c;可以将应用程序及其依赖项打包到一个轻量级的容器中&#xff0c;以便在任何地方运行。以下是Docker的基本概念和优势&#xff1a; 基本概念&#xff1a; 镜像&#xff08;image&#xff09;&#xff1a;Docker的基本构建块&am…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...