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

Spring Boot 的 WebClient 实践教程

什么是 WebClient?

在 Spring Boot 中,WebClient 是 Spring WebFlux 提供的一个非阻塞、响应式的 HTTP 客户端,用于与 RESTful 服务或其他 HTTP 服务交互。相比于传统的 RestTemplate,WebClient 更加现代化,具有异步和非阻塞的特点,适合高性能、高并发的应用场景。

WebClient 的特点

非阻塞 I/O:适用于响应式编程模型,能高效处理大量并发请求。

功能强大:支持同步和异步调用,处理复杂的 HTTP 请求和响应,包括流式数据。

灵活的配置:可自定义超时、请求拦截器、认证方式等。

响应式编程支持:返回 Mono 或 Flux,与 Spring WebFlux 的响应式编程模型无缝集成。

引入依赖

在使用 WebClient 之前,需要确保 Spring Boot 项目已包含相关依赖。

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

配置及使用 WebClient

现在有以下服务

  • service1服务:http://localhost:8081/
  • service2服务:http://localhost:8082/
  • common服务:http://localhost:8079/

创建 WebClientConfig 配置类,为 service1 和 service2 配置独立的 WebClient。

package com.example.common.config;import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;
import reactor.netty.tcp.TcpClient;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;/*** 配置 WebClient,支持基础功能(独立 WebClient 实例)和高级特性(超时、拦截器、内存限制)。*/
@Configuration
public class WebClientConfig {/*** 配置 WebClient,用于调用 service1(http://localhost:8081)** @param builder WebClient.Builder 实例* @return 针对 service1 的 WebClient 实例*/@Bean(name = "service1WebClient")public WebClient service1WebClient(WebClient.Builder builder) {return builder.baseUrl("http://localhost:8081") // 配置 service1 的基本 URL.defaultHeader("Content-Type", "application/json") // 设置默认请求头.exchangeStrategies(ExchangeStrategies.builder().codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(16 * 1024 * 1024)) // 设置最大内存限制为 16MB.build()).filter(logRequest()) // 添加请求日志拦截器.filter(logResponse()) // 添加响应日志拦截器.build();}/*** 配置 WebClient,用于调用 service2(http://localhost:8082)** @param builder WebClient.Builder 实例* @return 针对 service2 的 WebClient 实例*/@Bean(name = "service2WebClient")public WebClient service2WebClient(WebClient.Builder builder) {return builder.baseUrl("http://localhost:8082") // 配置 service2 的基本 URL.defaultHeader("Content-Type", "application/json") // 设置默认请求头.filter(logRequest()) // 添加请求日志拦截器.filter(logResponse()) // 添加响应日志拦截器.build();}/*** 提供全局的 WebClient.Builder 配置,支持超时和高级功能。** @return 配置好的 WebClient.Builder*/@Beanpublic WebClient.Builder webClientBuilder() {// 配置 TCP 客户端,设置连接超时、读超时和写超时TcpClient tcpClient = TcpClient.create().option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000) // 连接超时 5秒.doOnConnected(connection ->connection.addHandlerLast(new ReadTimeoutHandler(5)) // 读超时 5秒.addHandlerLast(new WriteTimeoutHandler(5))); // 写超时 5秒// 使用配置的 TcpClient 创建 HttpClientHttpClient httpClient = HttpClient.from(tcpClient);// 创建 WebClient.Builder 并配置 HttpClient 和拦截器return WebClient.builder().clientConnector(new ReactorClientHttpConnector(httpClient)) // 配置 HttpClient.filter(logRequest()) // 请求日志拦截器.filter(logResponse()); // 响应日志拦截器}/*** 请求日志拦截器:记录请求的详细信息(方法和 URL)** @return ExchangeFilterFunction 拦截器*/private ExchangeFilterFunction logRequest() {return ExchangeFilterFunction.ofRequestProcessor(request -> {System.out.println("Request: " + request.method() + " " + request.url());return Mono.just(request);});}/*** 响应日志拦截器:记录响应的状态码** @return ExchangeFilterFunction 拦截器*/private ExchangeFilterFunction logResponse() {return ExchangeFilterFunction.ofResponseProcessor(response -> {System.out.println("Response status: " + response.statusCode());return Mono.just(response);});}
}

service1相应的接口

package cloud.service1.controller;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.Map;/*** Service1 的控制器类,用于处理与API相关的请求.* 该类被Spring框架管理,作为处理HTTP请求的一部分.*/
@RestController
@RequestMapping("/api/service1")
public class Service1Controller {/*** 获取Service1的数据信息.* * @return 包含服务信息的映射,包括服务名称和问候消息.*/@GetMapping("/data")public Map<String, String> getData() {// 返回一个不可变的映射,包含服务名称和问候消息return Map.of("service", "service1", "message", "Hello from Service1");}
}

service2相应的接口

package cloud.service2.controller;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.Map;/*** Service2的控制器类,用于处理与Service2相关的HTTP请求.* 该类被Spring框架管理,作为处理RESTful请求的控制器.*/
@RestController
@RequestMapping("/api/service2")
public class Service2Controller {/*** 处理GET请求到/api/service2/info,返回Service2的信息.* * @return 包含服务信息的Map,包括服务名称和欢迎消息.*/@GetMapping("/info")public Map<String, String> getInfo() {return Map.of("service", "service2", "message", "Hello from Service2");}
}

服务调用实现

package com.example.common.service;import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;/*** CommonService 类提供了对其他服务进行调用的方法* 它通过 WebClient 实例与 service1 和 service2 进行通信*/
@Service
public class CommonService {// 用于与 service1 通信的 WebClient 实例private final WebClient service1WebClient;// 用于与 service2 通信的 WebClient 实例private final WebClient service2WebClient;/*** 构造函数注入两个 WebClient 实例** @param service1WebClient 用于 service1 的 WebClient* @param service2WebClient 用于 service2 的 WebClient*/public CommonService(@Qualifier("service1WebClient") WebClient service1WebClient,@Qualifier("service2WebClient") WebClient service2WebClient) {this.service1WebClient = service1WebClient;this.service2WebClient = service2WebClient;}/*** 调用 service1 的接口** @return 来自 service1 的数据*/public Mono<String> callService1() {// 通过 service1WebClient 调用 service1 的 API,并处理可能的错误return service1WebClient.get().uri("/api/service1/data").retrieve().bodyToMono(String.class).onErrorResume(e -> {// 错误处理:打印错误信息并返回错误提示System.err.println("Error calling service1: " + e.getMessage());return Mono.just("Error calling service1");});}/*** 调用 service2 的接口** @return 来自 service2 的数据*/public Mono<String> callService2() {// 通过 service2WebClient 调用 service2 的 API,并处理可能的错误return service2WebClient.get().uri("/api/service2/info").retrieve().bodyToMono(String.class).onErrorResume(e -> {// 错误处理:打印错误信息并返回错误提示System.err.println("Error calling service2: " + e.getMessage());return Mono.just("Error calling service2");});}
}
package com.example.common.controller;import com.example.common.service.CommonService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;/*** 通用控制器类,处理与通用服务相关的API请求*/
@RestController
@RequestMapping("/api/common")
public class CommonController {// 注入通用服务接口,用于调用具体的服务方法private final CommonService commonService;/*** 构造函数注入CommonService实例** @param commonService 通用服务接口实例*/public CommonController(CommonService commonService) {this.commonService = commonService;}/*** 调用 service1 的接口** @return service1 的响应数据*/@GetMapping("/service1")public Mono<String> getService1Data() {return commonService.callService1();}/*** 调用 service2 的接口** @return service2 的响应数据*/@GetMapping("/service2")public Mono<String> getService2Info() {return commonService.callService2();}
}

测试接口

优化实践

将上述代码进一步优化和整合以确保代码可维护性和高效性。

package com.example.common.config;import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;
import reactor.netty.tcp.TcpClient;/*** 配置 WebClient 的各类设置和日志记录*/
@Configuration
public class WebClientConfig {/*** 全局 WebClient.Builder 配置** @return 配置好的 WebClient.Builder*/@Beanpublic WebClient.Builder webClientBuilder() {// 配置 TCP 客户端的连接、读取、写入超时时间TcpClient tcpClient = TcpClient.create().option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000) // 连接超时.doOnConnected(conn -> conn.addHandlerLast(new ReadTimeoutHandler(5)) // 读超时.addHandlerLast(new WriteTimeoutHandler(5))); // 写超时// 将 TCP 客户端配置应用到 HTTP 客户端HttpClient httpClient = HttpClient.from(tcpClient);// 配置 WebClient 构建器,包括 HTTP 连接器、交换策略、请求和响应日志return WebClient.builder().clientConnector(new ReactorClientHttpConnector(httpClient)).exchangeStrategies(ExchangeStrategies.builder().codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(16 * 1024 * 1024)) // 内存限制.build()).filter(logRequest())  // 请求日志.filter(logResponse()); // 响应日志}/*** 针对 service1 的 WebClient 配置** @param builder 全局配置的 WebClient.Builder* @return 配置好的 WebClient 实例*/@Bean(name = "service1WebClient")public WebClient service1WebClient(WebClient.Builder builder) {// 为 service1 配置特定的 base URL 和默认头部return builder.baseUrl("http://localhost:8081").defaultHeader("Content-Type", "application/json").build();}/*** 针对 service2 的 WebClient 配置** @param builder 全局配置的 WebClient.Builder* @return 配置好的 WebClient 实例*/@Bean(name = "service2WebClient")public WebClient service2WebClient(WebClient.Builder builder) {// 为 service2 配置特定的 base URL 和默认头部return builder.baseUrl("http://localhost:8082").defaultHeader("Content-Type", "application/json").build();}/*** 请求日志拦截器** @return 记录请求日志的 ExchangeFilterFunction*/private ExchangeFilterFunction logRequest() {// 拦截请求并打印请求方法和URLreturn ExchangeFilterFunction.ofRequestProcessor(request -> {System.out.println("Request: " + request.method() + " " + request.url());return Mono.just(request);});}/*** 响应日志拦截器** @return 记录响应日志的 ExchangeFilterFunction*/private ExchangeFilterFunction logResponse() {// 拦截响应并打印响应状态码return ExchangeFilterFunction.ofResponseProcessor(response -> {System.out.println("Response status: " + response.statusCode());return Mono.just(response);});}
}
package com.example.common.service;import org.springframework.core.ParameterizedTypeReference;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;import java.util.Map;/*** CommonService 类提供了调用两个不同服务的公共方法,并合并其结果*/
@Service
public class CommonService {// service1 的 WebClient 实例private final WebClient service1WebClient;// service2 的 WebClient 实例private final WebClient service2WebClient;/*** 构造函数注入 WebClient 实例** @param service1WebClient service1 的 WebClient* @param service2WebClient service2 的 WebClient*/public CommonService(WebClient service1WebClient, WebClient service2WebClient) {this.service1WebClient = service1WebClient;this.service2WebClient = service2WebClient;}/*** 异步调用 service1 和 service2,并返回合并结果(JSON 格式)** @return 包含两个服务响应的 Mono 对象*/public Mono<Map<String, Map<String, String>>> callServicesAsync() {// 调用 service1,返回 Map 响应Mono<Map<String, String>> service1Response = service1WebClient.get()// 设置请求的URI.uri("/api/service1/data")// 检索响应.retrieve()// 处理错误状态.onStatus(// 检查状态是否为4xx或5xxstatus -> status.is4xxClientError() || status.is5xxServerError(),// 如果是,创建一个运行时异常response -> Mono.error(new RuntimeException("Service1 Error: " + response.statusCode())))// 将响应体转换为Mono<Map<String, String>>.bodyToMono(new ParameterizedTypeReference<Map<String, String>>() {})// 处理错误.onErrorResume(e -> {// 打印错误信息System.err.println("Error calling service1: " + e.getMessage());// 返回一个包含错误信息的Mapreturn Mono.just(Map.of("error", "Fallback response for service1"));});// 调用 service2,返回 Map 响应Mono<Map<String, String>> service2Response = service2WebClient.get()// 设置请求的URI.uri("/api/service2/info")// 检索响应.retrieve()// 处理错误状态.onStatus(// 检查状态是否为4xx或5xxstatus -> status.is4xxClientError() || status.is5xxServerError(),// 如果是,创建一个运行时异常response -> Mono.error(new RuntimeException("Service2 Error: " + response.statusCode())))// 将响应体转换为Mono<Map<String, String>>.bodyToMono(new ParameterizedTypeReference<Map<String, String>>() {})// 处理错误.onErrorResume(e -> {// 打印错误信息System.err.println("Error calling service2: " + e.getMessage());// 返回一个包含错误信息的Mapreturn Mono.just(Map.of("error", "Fallback response for service2"));});// 合并两个响应return Mono.zip(service1Response, service2Response, (response1, response2) -> Map.of("service1", response1,"service2", response2))// 处理合并过程中的错误.onErrorResume(e -> {// 打印错误信息System.err.println("Error combining responses: " + e.getMessage());// 返回一个包含错误信息的Mapreturn Mono.just(Map.of("error", Map.of("status", "error","message", e.getMessage() // 捕获异常并输出信息)));});}
}
package com.example.common.controller;import com.example.common.service.CommonService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;import java.util.Map;@RestController
@RequestMapping("/api/common")
public class CommonController {private final CommonService commonService;public CommonController(CommonService commonService) {this.commonService = commonService;}/*** 提供异步调用的 REST 接口,返回 JSON 格式的数据*/@GetMapping("/service")public Mono<Map<String, Map<String, String>>> getServicesData() {System.out.println("Received request for combined service data");return commonService.callServicesAsync().doOnSuccess(response -> System.out.println("Successfully retrieved data: " + response)).doOnError(error -> System.err.println("Error occurred while fetching service data: " + error.getMessage()));}
}

测试接口 

结语 

WebClient 是一个功能强大且灵活的非阻塞 HTTP 客户端,特别适合在高并发和响应式编程场景下使用,是替代传统 RestTemplate 的优秀选择。在实际项目中,通过合理配置(如超时、连接池)和优化(如负载均衡、重试机制),可以显著提高服务间通信的效率和可靠性,降低延迟和资源消耗。

同时,结合 Spring WebFlux 提供的响应式编程支持,WebClient 能够更好地应对微服务架构中复杂的通信需求,成为开发现代分布式系统的重要工具。

相关文章:

Spring Boot 的 WebClient 实践教程

什么是 WebClient&#xff1f; 在 Spring Boot 中&#xff0c;WebClient 是 Spring WebFlux 提供的一个非阻塞、响应式的 HTTP 客户端&#xff0c;用于与 RESTful 服务或其他 HTTP 服务交互。相比于传统的 RestTemplate&#xff0c;WebClient 更加现代化&#xff0c;具有异步和…...

STM32笔记(串口IAP升级)

一、IAP简介 IAP&#xff08;In Application Programming&#xff09;即在应用编程&#xff0c; IAP 是用户自己的程序在运行过程中对 User Flash 的部分区域进行烧写&#xff0c;目的是为了在产品发布后可以方便地通过预留的通信口对产 品中的固件程序进行更新升级。 通常实…...

Ollama - 简化使用本地大语言模型

学习完用 Transformers 和 llama.cpp 使用本地大语言模型后&#xff0c;再继续探索如何使用 Ollama 跑模型。Ollama 让运行和管理大语言模型变得更为简单&#xff0c;它构建在 llama.cpp 之上&#xff0c;并有优化&#xff0c;性能表现同样不俗。下面罗列一下它的特点 从它的 …...

圆域函数的傅里叶变换和傅里叶逆变换

空域圆域函数的傅里叶变换 空域圆域函数&#xff08;也称为空间中的圆形区域函数&#xff09;通常指的是在二维空间中&#xff0c;以原点为中心、半径为 a a a的圆内取值为1&#xff0c;圆外取值为0的函数。这种函数可以表示为&#xff1a; f ( x , y ) { 1 if x 2 y 2 ≤ …...

智能交易模型的全景探索:量化技术的进步与未来

随着金融市场日益复杂化&#xff0c;量化交易模型在投资领域扮演着愈加重要的角色。这些模型通过数据驱动和技术创新&#xff0c;赋能投资者在高度波动的市场中寻找确定性收益点。本文将从技术进步、模型构建、应用优势和未来发展四个方面&#xff0c;探讨量化交易模型的演变与…...

mysql学习

1、 数据库的三范式是什么&#xff1f; 2、特点 - 永久性&#xff1a;从本质上来说数据库中的数据以计算机文件的方式存储在磁盘上- 结构性&#xff1a;数据不是杂乱无章的存储- 大量&#xff1a;只受到磁盘空间的影响 3、 Myisam与innodb的区别 4、mysql架构 开始编程语言进…...

小白新手村冒险之“烤”json串

JSON是什么&#xff1f; JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;易于人阅读和编写&#xff0c;同时也易于机器解析和生成。它基于JavaScript的一个子集&#xff0c;但是JSON是独立于语言的文本格式&#xff0c;许多编…...

SQL基础入门—— 简单查询与条件筛选

在SQL中&#xff0c;查询是从数据库中获取数据的核心操作&#xff0c;而条件筛选是查询中不可或缺的一部分。通过使用条件筛选&#xff0c;我们可以精准地从大量数据中提取我们需要的信息。本节将详细讲解如何使用SQL进行简单查询与条件筛选&#xff0c;包含常见的条件运算符和…...

Java线程池种类及具体应用场景

Java线程池种类及具体应用场景 在实际开发中&#xff0c;选择合适的线程池类型至关重要&#xff0c;不同场景有不同的线程池需求。本文将结合线程池种类和具体应用示例&#xff0c;详细说明每种线程池的使用场景和适用情况。 一、固定大小线程池&#xff08;FixedThreadPool&a…...

3D建筑模型的 LOD 规范

LOD&#xff08;细节层次&#xff09; 是3D城市建模中用于表示建筑模型精细程度的标准化描述不同的LOD适用于不同的应用场景 LOD是3D建模中重要的分级标准&#xff0c;不同层级适合不同精度和用途的需求。 从LOD0到LOD4&#xff0c;细节逐渐丰富&#xff0c;复杂性和精度也逐…...

掌上单片机实验室 — RT - Thread+ROS2 浅尝(26)

前面化解了Micro_ROS通讯问题&#xff0c;并在 RT-Thread Studio 环境下&#xff0c;使用Micro_ROS软件包中的例程&#xff0c;实现了STM32F411CE核心板和ROS2主机的通讯。之后还尝试修改例程 micro_ros_sub_twist.c &#xff0c;实现了接收 turtle_teleop_key 所发出的 turtle…...

同步时序电路——描述

这部分要求了解一些触发器的状态方程&#xff1a; R-S触发器&#xff1a; D触发器&#xff1a; JK触发器&#xff1a; 时序电路&#xff1a;任一时刻的输出既与即刻输入有关(若有输入)&#xff0c;还与电路当时的状态有关(和以前的输入有关)&#xff0c;即电路具有记忆能力。 时…...

.net的winfrom程序 窗体透明打开窗体时出现在屏幕右上角

窗体透明&#xff0c; 将Form的属性Opacity&#xff0c;由默认的100% 调整到 80%&#xff0c;这个数字越小越透明(尽量别低于50%&#xff0c;不信你试试看)&#xff01; 打开窗体时出现在屏幕右上角 //构造函数 public frmCalendarList() {InitializeComponent();//打开窗体&…...

反爬虫机制

许多网站会采取措施来防止爬虫频繁访问或抓取大量内容&#xff0c;这些措施被称为反爬虫机制。常见的反爬手段包括&#xff1a; IP 限制&#xff1a;通过检测频繁访问的 IP 地址&#xff0c;限制该 IP 的访问。 请求频率限制&#xff1a;网站可能通过检测请求间隔过短来判断是…...

ML 系列:第 31 节— 机器学习中的协方差和相关性

文章目录 一、说明二、协方差和相关性2.1 协方差的概念2.1 相关 三、有关关联的高级主题 &#xff08;有关详细信息&#xff09;3.1 相关性和独立性3.2 零相关性和依赖性示例 四、相关性和因果关系五、结论 一、说明 协方差量化了两个随机变量协同变化的程度。当一个变量的较高…...

registry 删除私有仓库镜像

原文链接&#xff1a;https://blog.csdn.net/yogima/article/details/122172744 如果需要彻底删除&#xff0c;只需进行register 磁盘删除镜像 彻底删除了&#xff0c;就可以到达彻底删除的目的。 如果只需要软删除&#xff0c;则只需进行通过API删除。 curl --header "Ac…...

初识java(3)

大家好&#xff0c;今天我们来讲讲我们的老伙计-变量&#xff0c;在哪一门编程语言中&#xff0c;变量的作用都是不可或缺的&#xff0c;那么下面我们就来详细了解一下java中的变量。 一.变量概念 在程序中&#xff0c;除了有始终不变的常量外&#xff0c;有些内容可能会经常…...

前端JavaScript(一)---基本介绍

Javascript是一种由Netscape(网景)的LiveScript发展而来的原型化继承的面向对象的动态类型的区分大小写的客户端脚本语言&#xff0c;主要目的是为了解决服务器端语言&#xff0c;比如Perl&#xff0c;遗留的速度问题&#xff0c;为客户提供更流畅的浏览效果。当时服务端需要对…...

【Linux打怪升级记 | 报错02】-bash: 警告:setlocale: LC_TIME: 无法改变区域选项 (zh_CN.UTF-8)

&#x1f5fa;️博客地图 &#x1f4cd;1、报错发现 &#x1f4cd;2、原因分析 &#x1f4cd;3、解决办法 &#x1f4cd;4、测试结果 1、报错发现 装好了CentOS操作系统&#xff0c;使用ssh远程登陆CentOS&#xff0c;出现如下告警信息&#xff1a; bash: 警告:setlocale…...

P1198 [JSOI2008] 最大数

P1198 [JSOI2008] 最大数https://www.luogu.com.cn/problem/P1198 牵制芝士&#xff1a;单调队列 思路&#xff1a; 我们的任务是找出一个区间最大值的 因为插入的数与上一次的答案有关 所以它是强制在线的&#xff08;真无语了&#xff09; 我们可以在每次插入时整一个叫…...

嵌入式串口通信 基于芯片STC8H8K64U 串口通信入门001

引言 差不多有四年的时间没有写csdn的原创文章了。一方面是由于家庭的角色转换,已为人母,家中的很多琐事牵绊了我。另一方面是因为工作确实也非常的忙碌。工作需要,也会不断地学习新的知识和复习旧的知识,思来想去,还是决心把工作中的经验心得和遇到的问题,和各位程序猿朋…...

基于Java的小程序电商商城开源设计源码

近年来电商模式的发展越来越成熟&#xff0c;基于 Java 开发的小程序电商商城开源源码&#xff0c;为众多开发者和企业提供了构建个性化电商平台的有力工具。 基于Java的电子商城购物平台小程序的设计在手机上运行&#xff0c;可以实现管理员&#xff1b;首页、个人中心、用户…...

[OpenHarmony5.0][Docker][环境]OpenHarmony5.0 Docker pull线上镜像方式构建编译环境

T. 已测试目录 主机类型主机版本Docker镜像版本结果WSL2Ubuntu22.04Ubuntu20.04PASSWSL2Ubuntu22.04Ubuntu18.04PASS R. 软硬件要求&#xff1a; 硬件&#xff1a; 设备容量备注硬盘>500G多版本系统测试&#xff0c;必须固态&#xff0c;否则编译卡死硬盘>300G单系统…...

计算机网络八股整理(二)

计算机网络八股整理&#xff08;二&#xff09; 应用层 1&#xff1a;dns的全称了解过吗&#xff1f; dns全称domain-name-system&#xff0c;翻译过来就是域名系统&#xff0c;是在计算机网络中将域名转换成ip地址的分布式数据库系统&#xff1b; 域名服务器的层级类似一个树…...

华财术_号卡分销平台讲解(四大运营商+手机卡)

【号卡分销平台对比讲解稿】 大家好&#xff0c;今天我们来详细对比几款热门的号卡分销平台&#xff0c;帮助您找到最适合自己的合作伙伴。我们将从佣金结算、数据安全、功能特性、用户体验以及适用人群等多个维度进行剖析&#xff0c;让您一目了然各平台的优劣。 一、号易号…...

fatal error in include chain (rtthread.h):rtconfig.h file not found

项目搜索这个文件 rtconfig 找到后将其复制粘贴到 你的目录\Keil\ARM\ARMCC\include 应该还有cJSON&#xff0c;rtthread.h和 等也复制粘贴下...

服务器记录所有用户docker操作,监控删除容器/镜像的人

文章目录 使用场景安装auditd添加docker审计规则设置监控日志大小与定期清除查询 Docker 操作日志查看所有用户&#xff0c;所有操作日志查看特定用户的 Docker 操作查看所有用户删除容器/镜像日志过滤特定时间范围内日志 使用场景 多人使用的服务器&#xff0c;使用的docker …...

电磁继电器

它的控制原理很简单&#xff0c;当我们给它的线圈接电&#xff0c;这个线圈就有了磁性&#xff0c;它上面的衔铁就会被吸引&#xff0c;这样小灯泡就会点亮 继电器于MOS管的差别在于&#xff0c;继电器可以很轻松的胜任高电压、大电流的场合 我们从外壳上可以看到 30VDC&#x…...

Hadoop生态圈框架部署(九)- Hive部署

文章目录 前言一、Hive部署&#xff08;手动部署&#xff09;下载Hive1. 上传安装包2. 解压Hive安装包2.1 解压2.2 重命名2.3 解决guava冲突 3. 配置Hive3.1 配置Hive环境变量3.2 修改 hive-site.xml 配置文件3.3 配置MySQL驱动包3.3.1 下在MySQL驱动包3.3.2 上传MySQL驱动包3.…...

thread_id_key != 0x7777(`fibers` 包与 Node.js 16 及以上版本存在兼容性问题)

文章目录 fibers4.0.3 与 node-v16.13.2-win-x64 的兼容性1. Node.js 版本兼容性2. 特定包版本 (fibers4.0.3)3. 解决方案和替代方案 结论解决方案 运行yarn serve 启动项目&#xff0c;就会弹出上述错误。 fibers4.0.3 与 node-v16.13.2-win-x64 的兼容性 要判断 fibers4.0.3…...

LabVIEW实现UDP通信

目录 1、UDP通信原理 2、硬件环境部署 3、云端环境部署 4、UDP通信函数 5、程序架构 6、前面板设计 7、程序框图设计 8、测试验证 本专栏以LabVIEW为开发平台&#xff0c;讲解物联网通信组网原理与开发方法&#xff0c;覆盖RS232、TCP、MQTT、蓝牙、Wi-Fi、NB-IoT等协议。 结合…...

hive的存储格式

1&#xff09; 四种存储格式 hive的存储格式分为两大类&#xff1a;一类纯文本文件&#xff0c;一类是二进制文件存储。 Hive支持的存储数据的格式主要有&#xff1a;TEXTFILE、SEQUENCEFILE、ORC、PARQUET 第一类&#xff1a;纯文本文件存储 textfile: 纯文本文件存储格式…...

设置Mysql5.6允许外网访问

设置mysql用户支持外网访问步骤&#xff1a; 需要使用root权限登录mysql&#xff0c;更新mysql.user表&#xff0c;设置指定用户的Host字段为%&#xff0c;默认一般为127.0.0.1或者localhost。 1.登录数据库 1 mysql -u root -p 输入密码 1 mysql> use mysql; 2.查询hos…...

【智能制造-44】装配仿真

装配仿真包含以下功能模块&#xff1a; 零件建模与导入模块 功能描述&#xff1a; 能够创建简单的几何零件&#xff0c;如立方体、圆柱体、球体等基本形状。这对于一些标准件或者形状规则的零件来说&#xff0c;可以直接在装配仿真软件中生成&#xff0c;方便快捷。 支持多种…...

如何借助AI生成PPT,让创作轻松又高效

PPT是现代职场中不可或缺的表达工具&#xff0c;但同时也可能是令人抓狂的时间杀手。几页幻灯片的制作&#xff0c;常常需要花费数小时调整字体、配色与排版。AI的飞速发展为我们带来了革新——AI生成PPT的技术不仅让制作流程大大简化&#xff0c;还重新定义了效率与创意的关系…...

【工具变量】城市供应链创新试点数据(2007-2023年)

一、测算方式&#xff1a;参考C刊《经济管理》沈坤荣和乔刚老师&#xff08;2024&#xff09;的做法&#xff0c;使用“供应链创新与应用试点”的政策虚拟变量&#xff08;TreatPost&#xff09;表征。若样本城市为试点城市&#xff0c;则赋值为 1&#xff0c;否则为 0&#xf…...

线程的生命周期

计时等待&#xff08;Timed Waiting&#xff09;状态&#xff1a;这是等待状态的一种特殊情况&#xff0c;当线程调用带有超时参数的等待方法&#xff08;如Thread.sleep(long millis)、Object.wait(long timeout)等&#xff09;时会进入计时等待状态。例如&#xff0c;Thread.…...

Python入门(18)--实战项目

机器学习实战项目指南 &#x1f916; 项目概览 &#x1f310; 本项目是一个综合性的机器学习入门实战指南&#xff0c;通过实际案例展示机器学习项目的完整生命周期&#xff0c;包括数据处理、模型训练、评估和部署等关键环节。 1. 系统架构 &#x1f3d7;️ 1.1 核心组件 …...

DRM(数字权限管理技术)防截屏录屏----视频转hls流加密、web解密播放

提示&#xff1a;视频转hls流加密、web解密播放 需求&#xff1a;研究视频截屏时&#xff0c;播放器变黑&#xff0c;所以先研究的视频转hls流加密 文章目录 [TOC](文章目录) 前言一、工具ffmpeg、openssl二、后端nodeexpress三、web播放四、文档总结 前言 ‌HLS流媒体协议‌&a…...

在linux上部署Tomcat方法

上传jdk,配置运行环境 解压jdk安装包 将jdk文件夹移动到/usr/local/jdk目录下 配置java环境变量vim /etc/profile 使环境变量生效&#xff0c;并且查看是否配置成功 安装tomcat&#xff0c;上传tomcat软件包 解压tomcat软件包 将tomcat解压文件移动到/usr/local/tomcat/下 启动…...

Git 使用问题与解决方案

Git 使用问题与解决方案 目录 常见错误及原因分析检查当前使用 HTTPS 或 SSH如何切换远程仓库到 SSHSSH 密钥的配置与验证错误解决步骤总结与参考 1. 常见错误及原因分析 错误提示 fatal: unable to access https://github.com/username/repository.git/: Failed to connect…...

LeetCode 热题 100_最大子数组和(13_53)(贪心算法 ||动态规划)

LeetCode 热题 100_最大子数组和&#xff08;13_53&#xff09; 题目描述&#xff1a;输入输出样例&#xff1a;题解&#xff1a;解题思路&#xff1a;代码实现&#xff08;思路二&#xff08;贪心算法 ||动态规划&#xff09;&#xff09;&#xff1a; 题目描述&#xff1a; …...

Z2400023基于Java+Servlet+jsp+mysql的酒店管理系统的设计与实现 源码 调试 文档

酒店管理系统的设计与实现 1.摘要2.主要功能3. 项目技术栈运行环境 4.系统界面截图5.源码获取 1.摘要 本文介绍了一个基于Java的酒店管理系统&#xff0c;该系统采用Servlet、JSP、JDBC以及c3p0等技术构建&#xff0c;为酒店提供了一个全面的管理平台。该系统不仅适合酒店进行…...

T3 TensorFlow入门实战——天气识别

&#x1f368; 本文為&#x1f517;365天深度學習訓練營 中的學習紀錄博客&#x1f356; 原作者&#xff1a;K同学啊 | 接輔導、項目定制 一、前期准备 1. 导入数据 # Import the required libraries import numpy as np import os,PIL,pathlib import matplotlib.pyplot as …...

vue3 多种方式接受props,定义ref,reactive

定义props 1 第一种 interface AddType { dialogStudyVisible: boolean; } const props defineProps<AddType>(); 第二种 // const props defineProps({ // dialogStudyVisible:{ // type:Boolean, // default:false // } // }) 第三种 // const …...

15:00面试,15:06就出来了,问的问题有点变态。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到9月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40%…...

vue3 数字滚动插件vue3-count-to

安装 npm i vue3-count-to -S 引入 import { CountTo } from vue3-count-to 使用 <countTo :startVal"0" :endVal"57.63" :decimals"0" :duration"3000"></countTo> 所有配置...

Android 手写签名板

文章目录 Android 手写签名板概述效果代码实现源码下载 Android 手写签名板 概述 手写签名板功能&#xff0c;支持图片保存、支持去除空白区域。 效果 生成图片效果&#xff1a; 代码实现 定义属性&#xff1a; <declare-styleable name"SignatureView">&…...

Java基础夯实——2.9 多线程如何共享数据

在 Java 多线程编程中&#xff0c;共享数据通过以下几种方式实现&#xff1a; 1. 使用共享对象 多个线程可以通过引用同一个对象来实现数据共享。例如&#xff1a; class SharedData {private int count;public synchronized void increment() {count;}public synchronized …...

京准电钟:NTP网络校时服务器从入门到精准

京准电钟&#xff1a;NTP网络校时服务器从入门到精准 京准电钟&#xff1a;NTP网络校时服务器从入门到精准 1.前言 由计算机网络系统组成的分布式系统&#xff0c;若想协调一致进行&#xff1a;IT行业的“整点开拍”、“秒杀”、“Leader选举”&#xff0c;通信行业的“同步…...