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

Spring Boot 拦截器:解锁5大实用场景

一、Spring Boot中拦截器是什么

  在Spring Boot中,拦截器(Interceptor)是一种基于AOP(面向切面编程)思想的组件,用于在请求处理前后插入自定义逻辑,实现权限校验、日志记录、性能监控等非业务功能。

  其核心作用是在不修改业务代码的前提下,对请求进行统一处理,类似于Servlet中的Filter,但更贴近Spring MVC的体系。

二、拦截器与过滤器的区别

在这里插入图片描述

三、拦截器主要方法

在实现拦截器时,HandlerInterceptor接口提供了三个主要方法,它们在请求处理的不同阶段发挥着重要作用。

preHandle
  这个方法在请求进入Controller之前被调用 。它的返回值是一个布尔类型,如果返回true,请求将继续被处理,进入Controller。
   如果返回false,请求将被拦截,后续的Controller方法将不会被执行。在这个方法中,我们通常可以进行一些前置的处理操作,比如用户认证、权限校验、日志记录等。​

postHandle
  当Controller方法执行完毕后,视图渲染之前,这个方法会被调用 。

  在这个方法中,我们可以对ModelAndView进行一些操作,比如添加额外的模型数据,修改视图名称等。需要注意的是,如果在preHandle方法中返回了false,这个方法将不会被执行。​

afterCompletion
  在整个请求处理完成,包括视图渲染之后,这个方法会被调用。无论请求处理过程中是否发生异常,只要preHandle方法返回true,这个方法就会被执行。

  我们可以在这个方法中进行一些资源清理、记录日志等收尾工作。如果请求处理过程中发生了异常,异常信息会通过 ex 参数传递进来,我们可以根据这个参数进行相应的异常处理。

@Component
public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 在请求处理之前执行的逻辑System.out.println("preHandle被调用,请求即将进入Controller");return true; // 返回true表示放行请求,返回false则拦截请求}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {// 在请求处理之后,视图渲染之前执行的逻辑System.out.println("postHandle被调用,Controller方法已执行完毕,视图即将渲染");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 在整个请求处理完成,包括视图渲染之后执行的逻辑System.out.println("afterCompletion被调用,整个请求已处理完毕");}
}
@Configuration
public class WebMvcConfig1 implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**") // 拦截所有请求.excludePathPatterns("/static/**"); // 排除/static目录下的静态资源请求}
}

四、5 种常见的拦截器使用场景

1.用户认证拦截器

  用户认证拦截器的作用就是在用户请求进入 Controller 之前,验证用户的登录状态。如果用户已经登录,允许请求继续处理。如果用户未登录,则返回错误信息或者重定向到登录页面。

@Component
public class JwtHandlerInterceptor implements HandlerInterceptor {@Autowiredprivate JwtTokenProvider jwtTokenProvider;@Autowiredprivate UserInfoService userInfoService;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {if (!(handler instanceof HandlerMethod)) {return true;}// 取出tokenString token = request.getHeader("token");if (!jwtTokenProvider.validateToken(token)) {response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);response.getWriter().write("{\"error\": \"Token已失效,请重新登录\"}");return false;}HandlerMethod handlerMethod = (HandlerMethod) handler;Method method = handlerMethod.getMethod();// 判断方法上是否有NoAuth注解,如果有则跳过认证if (method.isAnnotationPresent(NoAuth.class)) {return true;}String username = jwtTokenProvider.getUsernameFromJWT(token);User user = userInfoService.getUserInfoByUserName(username);if (user == null) {response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);response.getWriter().write("{\"error\": \"用户不存在\"}");return false;}// 判断角色权限HasRoles hasRoles = handlerMethod.getMethodAnnotation(HasRoles.class);if (!Objects.isNull(hasRoles)) {// 检查用户是否有所需角色String[] roles = hasRoles.value();boolean hasRole = false;// 角色校验 ...if (!hasRole) {response.setStatus(HttpServletResponse.SC_FORBIDDEN);response.getWriter().write("{\"error\": \"权限不足\"}");return false;}}// 将用户信息放入请求属性request.setAttribute("currentUser", user);return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {HandlerInterceptor.super.afterCompletion(request, response, handler, ex);}
}

  在WebMvcConfig配置类中,将JwtHandlerInterceptor注册到Spring的拦截器链中,并设置拦截路径为所有请求,排除了登录和注册接口,因为这两个接口不需要用户登录就可以访问。

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new JwtHandlerInterceptor()).addPathPatterns("/**")// 拦截所有请求.excludePathPatterns("/login","/register");// 排除登录和注册接口}}

  通过这样的配置,就可以实现对用户登录状态的验证,确保只有登录用户才能访问受保护的资源。

2.日志记录拦截器

  日志记录对于系统的运维和故障排查非常重要。日志记录拦截器可以在请求处理的前后记录请求的相关信息,比如请求的 URL、请求方法、请求参数、客户端 IP 等。这些日志信息可以帮助我们了解系统的运行情况,分析用户行为,在出现问题时快速定位问题。

@Component
public class RequestLoggingInterceptor implements HandlerInterceptor {private static final Logger logger = LoggerFactory.getLogger(RequestLoggingInterceptor.class);@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {logger.info("Request URL: {}, Method: {}, IP: {}", request.getRequestURI(), request.getMethod(), request.getRemoteAddr());// 记录请求参数Map<String, String[]> paramMap = request.getParameterMap();StringBuilder params = new StringBuilder();if (!paramMap.isEmpty()) {for (Map.Entry<String, String[]> entry : paramMap.entrySet()) {params.append(entry.getKey()).append("=").append(String.join(",", entry.getValue())).append("&");}if (params.length() > 0) {params.deleteCharAt(params.length() - 1);}}// 记录请求体(仅POST/PUT/PATCH请求)String method = request.getMethod();String requestBody = "";if (HttpMethod.POST.matches(method) ||HttpMethod.PUT.matches(method) ||HttpMethod.PATCH.matches(method)) {// 使用包装请求对象来多次读取请求体ContentCachingRequestWrapper wrappedRequest =new ContentCachingRequestWrapper(request);// 为了触发内容缓存,我们需要获取一次输入流if (wrappedRequest.getContentLength() > 0) {wrappedRequest.getInputStream().read();requestBody = new String(wrappedRequest.getContentAsByteArray(),wrappedRequest.getCharacterEncoding());}}logger.info("Request URL: {}, Method: {}, IP: {},params: {},requestBody: {}", request.getRequestURI(), request.getMethod(), request.getRemoteAddr(), params, requestBody);return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {logger.info("Request to {} has been completed", request.getRequestURI());if (ex != null) {logger.error("An exception occurred during request handling", ex);}}
}

3.性能监控拦截器

  性能监控对于优化系统性能至关重要。性能监控拦截器可以用来计算和记录请求的处理时间,通过分析这些时间数据,我们可以找出系统中的性能瓶颈,进而进行针对性的优化。

@Component
public class PerformanceInterceptor implements HandlerInterceptor {private static final ThreadLocal<Long> startTimeThreadLocal = new ThreadLocal<>();@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {long startTime = System.currentTimeMillis();startTimeThreadLocal.set(startTime);return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {// 计算请求处理时间long endTime = System.currentTimeMillis();long startTime = startTimeThreadLocal.get();long executeTime = endTime - startTime;System.out.println("Request URL: " + request.getRequestURL() + ", Execution Time: " + executeTime + "ms");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {startTimeThreadLocal.remove();}
}

4.接口限流拦截器
  在高并发场景下,接口限流是保护系统的重要手段 。接口限流拦截器可以限制单位时间内对某个接口的访问次数,防止因大量请求导致系统资源耗尽,从而保证系统的稳定性和可用性 。

@Component
public class AccessLimitInterceptor implements HandlerInterceptor {@Autowiredprivate RedisTemplate<String, Integer> redisTemplate;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {if (!(handler instanceof HandlerMethod)) {return true;}HandlerMethod handlerMethod = (HandlerMethod) handler;AccessLimit accessLimit = handlerMethod.getMethodAnnotation(AccessLimit.class);if (accessLimit == null) {return true;}int seconds = accessLimit.seconds();int maxCount = accessLimit.maxCount();boolean needLogin = accessLimit.needLogin();if (needLogin) {// 检查用户登录状态,这里省略具体实现// 如果未登录,返回错误信息return false;}String key = request.getRemoteAddr() + request.getRequestURI();Integer count = redisTemplate.opsForValue().get(key);if (count == null) {redisTemplate.opsForValue().set(key, 1, seconds, TimeUnit.SECONDS);} else if (count < maxCount) {redisTemplate.opsForValue().increment(key, 1);} else {render(response, "请求过于频繁,请稍后再试");return false;}return true;}private void render(HttpServletResponse response, String msg) throws IOException {response.setContentType("application/json;charset=UTF-8");PrintWriter out = response.getWriter();out.write(msg);out.flush();out.close();}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}}

5.数据加密解密拦截器
  在数据传输和存储过程中,保护敏感数据的安全至关重要。数据加密解密拦截器可以在请求到达Controller之前对敏感数据进行加密,在响应返回给客户端之前对加密数据进行解密,确保数据在传输和处理过程中的安全性。

  比如在用户登录时,对用户输入的密码进行加密后再传输到服务器。在从数据库中查询用户的身份证号、手机号等敏感信息时,对查询结果进行解密后再返回给前端。

@Component
public class EncryptionInterceptor implements HandlerInterceptor {/*** 密钥*/private static final String KEY = "secret_key";@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 假设请求参数中有一个名为"sensitiveData"的敏感数据需要加密String sensitiveData = request.getParameter("sensitiveData");if (sensitiveData != null) {SecretKey secretKey = new SecretKeySpec(KEY.getBytes(), "AES");byte[] encryptedData = AESUtil.encrypt(sensitiveData, secretKey);String encryptedDataStr = Base64.getEncoder().encodeToString(encryptedData);// 将加密后的数据重新放回请求参数中request.setAttribute("sensitiveData", encryptedDataStr);}return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 假设响应中有一个名为"sensitiveResponseData"的敏感数据需要解密String sensitiveResponseData = (String) request.getAttribute("sensitiveResponseData");if (sensitiveResponseData != null) {SecretKey secretKey = new SecretKeySpec(KEY.getBytes(), "AES");byte[] decodedData = Base64.getDecoder().decode(sensitiveResponseData);String decryptedData = AESUtil.decrypt(decodedData, secretKey);// 将解密后的数据重新放回请求属性中,方便后续处理request.setAttribute("sensitiveResponseData", decryptedData);}}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);}
}

五、总结

  在 Spring Boot 开发中,拦截器就像是一把 “万能钥匙”,为我们提供了丰富的功能扩展和业务处理的可能性。

  希望大家在实际项目中,能够根据业务需求,灵活地运用这些拦截器,让我们的 Spring Boot 应用更加健壮、高效、安全。

  同时,拦截器还有很多值得深入探讨的地方,比如如何在拦截器中优雅地处理事务、如何实现更加复杂的动态拦截规则等 ,后续我们可以一起继续探索。

  如果大家在使用拦截器的过程中有任何问题或心得,欢迎在留言区分享交流。

相关文章:

Spring Boot 拦截器:解锁5大实用场景

一、Spring Boot中拦截器是什么 在Spring Boot中&#xff0c;拦截器&#xff08;Interceptor&#xff09;是一种基于AOP&#xff08;面向切面编程&#xff09;思想的组件&#xff0c;用于在请求处理前后插入自定义逻辑&#xff0c;实现权限校验、日志记录、性能监控等非业务功能…...

展锐 Android 15 锁定某个App版本的实现

Android 15 系统锁定Antutu版本的实现方法 在Android系统开发中,有时需要锁定特定应用的版本以确保系统稳定性或测试一致性。本文将介绍如何通过修改Android源码来锁定Antutu跑分软件的版本。 修改概述 这次修改主要涉及以下几个方面: 禁用产品复制文件的检查添加指定版本…...

有两个Python脚本都在虚拟环境下运行,怎么打包成一个系统服务,按照顺序启动?

环境&#xff1a; SEMCP searx.webapp python 问题描述&#xff1a; 有两个python脚本都在虚拟环境下运行&#xff0c;怎么打包成一个系统服务&#xff0c;按照顺序启动&#xff1f; 解决方案&#xff1a; 将这两个 Python 脚本打包成有启动顺序的系统服务&#xff0c;最…...

【Linux cmd】查找进程信息

1、包含 "Test" 关键字的进程 ps -ef | grep Test 显示系统中所有进程的详细信息&#xff0c;包括用户 ID&#xff08;UID&#xff09;、进程 ID&#xff08;PID&#xff09;、父进程 ID&#xff08;PPID&#xff09;、启动时间&#xff08;STIME&#xff09;、终端…...

与网格共舞 - 服务网格的运维与问题排查 (Istio 实例)

与网格共舞 - 服务网格的运维与问题排查 (Istio 实例) 在领略了服务网格(以 Istio 为例)在流量管理、可观测性和安全方面提供的强大能力后,我们自然会思考:如何将这个“神器”请进我们的生产环境,并让它稳定、可靠地运行?这需要我们关注运维层面的实践。 部署与升级:网…...

Python 脚本执行命令的深度探索:方法、示例与最佳实践

在现代软件开发过程中&#xff0c;Python 脚本常常需要与其他工具和命令进行交互&#xff0c;以实现自动化任务、跨工具数据处理等功能。Python 提供了多种方式来执行外部命令&#xff0c;并获取其输出&#xff0c;重定向到文件&#xff0c;而不是直接在终端中显示。这种能力使…...

PotPlayer 4K 本地万能影音播放器

今日分享一款来自吾爱论坛大佬分享的啥都能播的的本地播放器&#xff0c;不管是不管是普通视频、4K超清、蓝光3D&#xff0c;还是冷门格式&#xff0c;它基本都能搞定。而且运行流畅不卡顿&#xff0c;电脑配置低也能靠硬件加速&#xff0c;让你根本停不下来。 自带解码器&…...

2025年电工杯A题第一版本Q1-Q4详细思路求解+代码运行

A题 光伏电站发电功率日前预测问题 问题背景 光伏发电是通过半导体材料的光电效应&#xff0c;将太阳能直接转化为电能的技术。光伏电站是由众多光伏发电单元组成的规模化发电设施。 光伏电站的发电功率主要由光伏板表面接收到的太阳辐射总量决定&#xff0c;不同季节太阳光…...

基于阿里云DashScope API构建智能对话指南

背景 公司想对接AI智能体&#xff0c;用于客服系统&#xff0c;经过调研和实施&#xff0c;觉得DashScope 符合需求。 阿里云推出的DashScope灵积模型服务为开发者提供了便捷高效的大模型接入方案。本文将详细介绍如何基于DashScope API构建一个功能完善的智能对话系统&#x…...

HOW - 基于组件库组件改造成自定义组件基本规范

文章目录 Select 选择器改造1. 明确组件目标2. 定义组件 API3. 合理使用默认值4. 支持类型安全的 options 传递5. 支持 ForwardRef&#xff08;可选&#xff09;6. 封装样式&#xff08;可选&#xff09;7. 使用示例 ...props 位置推荐顺序&#xff1a;最后原因&#xff1a;简要…...

九州未来十三载:开源赋能 智启未来

2012年&#xff0c;九州未来以“开源赋能云边变革”为使命&#xff0c;开启中国开放云边基础架构服务的探索之路。十三载坚守深耕&#xff0c;我们始终以开源为翼&#xff0c;以算力为基&#xff0c;在科技浪潮中砥砺前行&#xff0c;见证并推动着AI时代的算力变革。 坚守初心丨…...

2025年AI搜索引擎发展洞察:技术革新与市场变革

引言&#xff1a;AI搜索的崛起与市场格局重塑 2024-2025年&#xff0c;AI搜索市场迎来了前所未有的变革期。随着DeepSeek-R1等先进大语言模型的推出&#xff0c;传统搜索引擎、AI原生搜索平台以及各类内容平台纷纷加速智能化转型&#xff0c;推动搜索技术从基础信息检索向深度…...

dify调用Streamable HTTP MCP应用

一、概述 上一篇文章&#xff0c;介绍了使用python开发Streamable HTTP MCP应用&#xff0c;链接&#xff1a;https://www.cnblogs.com/xiao987334176/p/18872195 接下来介绍dify如何调用MCP 二、插件 安装插件 需要安装2个插件&#xff0c;分别是&#xff1a;Agent 策略(支持 …...

HCIP实验五

一、实验拓扑图&#xff1a; 二、实验需求分析&#xff1a; 1. PreVal策略&#xff1a;要求确保R4通过R2到达192.168.10.0/24 &#xff0c;需在R4上针对去往该网段路由配置PreVal策略&#xff0c;为经R2的路径赋予更高优先值&#xff0c;影响本地路由表选路。 2. AS Path策略…...

java将图片转Base64字符串存储mysql数据库

1、mysql数据库的表里新增一个字段image_data&#xff0c;使用TEXT或LONGTEXT类型&#xff1a; CREATE TABLE IMAGES( id INT AUTO_INCREMENT PRIMARY KEY, image_name VARCHAR(255), image_data LONGTEXT, upload_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); 2、Java核心…...

题目 3330: 蓝桥杯2025年第十六届省赛真题-01 串

题目 3330: 蓝桥杯2025年第十六届省赛真题-01 串 时间限制: 2s 内存限制: 192MB 提交: 310 解决: 24 题目描述 给定一个由 0, 1, 2, 3 的二进制表示拼接而成的长度无限的 01 串。 其前若干位形如 011011100101110111 。 请求出这个串的前 x 位里有多少个 1 。 输入格…...

初识 Flask 框架

目录 1. Flask 框架概述 1.1 安装 Flask 1.2 创建你的第一个 Flask 应用 1.3 运行 Flask 应用 2. Flask 路由与视图函数 2.1 动态路由 2.2 支持多种 HTTP 请求方法 2.3 使用 Jinja2 模版渲染 HTML 2.5 模版继承与块 3. Flask 表单处理与用户输入 3.1 安装 Flask-WTF …...

MYSQL故障排查和环境优化

一、MySQL故障排查 1. 单实例常见故障 &#xff08;1&#xff09;连接失败类问题 ERROR 2002 (HY000): Cant connect to MySQL server 原因&#xff1a;MySQL未启动或端口被防火墙拦截。 解决&#xff1a;启动MySQL服务&#xff08;systemctl start mysqld&#xff09;或开放…...

vivado fpga程序固化

一般下载到fpga上的程序在掉电之后就会丢失&#xff0c;如果想要掉电之后程序不丢失&#xff0c;就需要将比特流文件固化到板载的flash上。 以下以我的7a100t开发板为例&#xff0c;介绍程序固化的流程 点击OK就可以下载了。 一个奇怪的问题 有一次我的一个工程固化之后&…...

OpenCV CUDA模块图像特征检测与描述------图像中快速检测特征点类cv::cuda::FastFeatureDetector

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::cuda::FastFeatureDetector 是 OpenCV 的 CUDA 加速模块中的一部分&#xff0c;用于在图像中快速检测特征点。FAST&#xff08;Features fro…...

SpringMVC(结合源码浅析工作流程)

SpringMVC 概念 Spring MVC 是基于前端控制器&#xff08;Front Controller&#xff09;设计模式的 Web 框架&#xff0c;在 Web 应用中指一个统一的入口&#xff0c;用来接收所有客户端请求&#xff0c;并统一进行分发、处理。在 SpringMVC 中&#xff0c;前端控制器就是 Di…...

学习STC51单片机13(芯片为STC89C52RC)

我去&#xff0c;兄弟们我们今天来学习一个牛逼 的硬件&#xff0c;它叫超声波测距模块HC—SR04 硬件&#xff1a;HC—SR04 哎&#xff0c;想当初最想要玩的就是这个模块&#xff0c;科技感十足&#xff0c;那现在就让我们玩玩吧 超声波测距传感器 原理就是说需要给Trig 10u…...

Claude 4 系列 Opus 4 与 Sonnet 4正式发布:Claude 4新特性都有哪些?

随着 Claude 4 系列&#xff08;Opus 4 与 Sonnet 4&#xff09;的正式发布&#xff0c;Anthropic 把自家大模型从“会聊天”推进到“能当自主代理”──不仅推理更深、上下文更长&#xff0c;还内置代码执行、多模态理解、工具调用等一揽子全新能力&#xff1b;同时&#xff0…...

Swagger API 未授权访问漏洞【原理扫描】修复

一、背景 漏洞名称&#xff1a;Swagger API 未授权访问漏洞【原理扫描】 风险等级&#xff1a;中 详细描述&#xff1a; Swagger 是一个规范和完整的框架&#xff0c;用于生成、描述、调用和可视化 RESTful 风格的 Web 服务&#xff0c;方便开发者快速了解和调试接口。但由于…...

深度“求索”:DeepSeek+Dify构建个人知识库

目录 前言 环境部署 安装Docker 安装Dify 配置Dify 部署知识库 创建应用 前言 在当今数字化信息爆炸的时代&#xff0c;数据隐私和个性化知识管理成为企业和个人关注的焦点。Dify&#xff0c;作为一款备受瞩目的开源 AI 应用开发平台&#xff0c;为用户提供了完整的私有…...

基于R语言的空间异质性数据分析技术

在自然和社会科学领域&#xff0c;存在大量与地理或空间相关的数据&#xff0c;这些数据通常具有显著的空间异质性。传统的统计学方法在处理这类数据时往往力不从心。基于R语言的一系列空间异质性数据分析方法&#xff0c;如地理加权回归&#xff08;GWR&#xff09;、地理加权…...

C++:动态刷新打印内容

目录 1.简介1.1 Display类原理简述 2.代码2.1 main.cpp&#xff1a;无注释版2.2 main.cpp&#xff1a;有注释版 3.编译运行 1.简介 本文介绍一个用于命令行动态覆盖输出的C实现&#xff08;Display类&#xff09;&#xff1b; 效果说明&#xff1a; 普通输出会直接换行显示。…...

网络学习-TCP协议(七)

一、TCP协议 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一种面向连接的、可靠的、基于字节流的传输层通信协议。 1、三次握手 客户端&#xff1a; 1、先发起连接&#xff0c;发送SYN置1&#xff0c;seqnum12345(随机值)----半连接…...

基于微信小程序的高校校园微活动管理系统设计与实现(源码+定制+开发)高校微信小程序校园活动发布与互动平台开发 面向大学生群体的校园活动移动平台设计与实现

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…...

Python 项目中安装 OpenAI 库的详细指南

在 Windows 系统中指定版本安装 OpenAI 库的指南 在 Windows 系统中&#xff0c;尤其是使用 Python 3.7.8 时&#xff0c;安装 OpenAI 库可能会遇到一些问题。本文将为你提供一个简单易懂的解决方案&#xff0c;帮助你成功安装指定版本的 OpenAI 库。 一、问题背景 当你在 W…...