【微服务】SpringBoot 自定义消息转换器使用详解
目录
一、前言
二、SpringBoot 内容协商介绍
2.1 什么是内容协商
2.2 内容协商机制深入理解
2.2.1 内容协商产生的场景
2.3 内容协商实现的常用方式
2.3.1 前置准备
2.3.2 通过HTTP请求头
2.3.2.1 操作示例
2.3.3 通过请求参数
三、SpringBoot 消息转换器介绍
3.1 HttpMessageConvertor介绍
3.1.1 常用的HttpMessageConvertor
3.2 如何确定使用哪个消息转换器
3.2.1 针对请求时的判断
3.2.2 针对响应时的判断
3.3 SpringMVC框架默认的消息转换器
3.3.1 源码跟踪
四、自定义消息转换器
4.1 自定义yaml消息转换器
4.1.1 引入如下的依赖
4.1.2 自定义yaml媒体类型
4.1.3 自定义HttpMessageConverter
4.1.4 配置消息转换器
4.1.5 测试与效果验证
五、写在文末
一、前言
在微服务开发中,客户端与服务端数据格式的协商和转换是一个经常接触的场景,不同的业务场景下,对于数据格式的要求也不同,比如有的客户端需要服务器响应XML格式数据,有的需要响应Json格式数据,这就是HTTP消息内容协商机制的源头,如何满足复杂多变的HTTP消息转换需求呢,本篇将详细分享如何在SpringBoot框架中完成自定义消息转换器的定制开发与使用。
二、SpringBoot 内容协商介绍
2.1 什么是内容协商
内容协商(Content Negotiation)是指服务器根据客户端请求来决定响应的内容类型(MIME 类型)。这使得应用程序可以根据客户端的需求返回不同格式的数据,如 JSON、XML 或 HTML 等。Spring Boot 通过 HttpMessageConverters 和 @RequestMapping 注解等机制来支持内容协商。
2.2 内容协商机制深入理解
内容协商机制是指服务器根据客户端的请求来决定返回资源的最佳表现形式
-
白话描述:客户端需要什么格式的数据,服务端就返回什么格式的数据。
比如:
-
客户端需要json,就响应json;
-
客户端需要xml,就响应xml;
-
客户端需要yaml,就响应yaml;
于是,你可能会有疑问,客户端接收数据时统一采用一种格式,例如Json不就行了,为什么还有那么多的格式要求呢?因为在实际开发中并不是这样的,比如在下面的场景:
-
遗留的老的系统中的某些业务,处理数据时仍然使用的是xml格式;
-
对于处理速度有要求的这种系统,明确要求使用json格式的数据;
-
对于安全要求比较高的系统,一般要求使用xml格式的数据;
-
某些业务场景下明确指定了某个类型的数据格式...
基于上面的场景,在当下流行的微服务开发模式下,不同的客户端可能需要后端返回不同格式的数据,于是,对于后端来说,就需要尽可能的适配和满足这种多样化的需求场景。
2.2.1 内容协商产生的场景
内容协商的产生具有一定的背景,下面列举了产生内容协商的一些因素
-
多客户端支持
-
浏览器用户可能希望看到 HTML 页面。
-
移动应用开发者可能更倾向于使用 JSON 数据来解析和展示信息。
-
某些旧系统或特定工具可能依赖于 XML 格式的响应。
-
-
提升用户体验
-
不同的客户端有不同的偏好和要求。允许客户端指定他们想要的内容类型可以提高交互效率,减少不必要的数据处理步骤,并确保最终呈现给用户的界面是最优化的。例如,某些设备可能更适合处理压缩过的二进制格式,而不是文本格式的数据。
-
-
遵照RESTful 原则
-
遵循 REST 架构风格的应用程序通常会根据资源的状态来确定响应的内容类型,而不是依赖于 URL 的变化。这意味着同一个 URI 可以根据请求的不同部分(如 HTTP 方法、查询参数或头部信息)返回不同类型的内容。内容协商是实现这一设计理念的关键机制之一。
-
2.3 内容协商实现的常用方式
通常来说,通过HTTP请求头(比如Accept)获取请求参数(如Format),来指定客户端偏好接收的内容类型(JSON或XML等),服务器会根据这些信息选择合适的格式进行响应。下面介绍2种比较常用的方式。
2.3.1 前置准备
为了后续的操作演示,请提前在工程中导入下面几个基础依赖
<properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.4</version><relativePath/></parent><dependencies><dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-yaml</artifactId></dependency><dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency></dependencies></project>
2.3.2 通过HTTP请求头
SpringBoot框架中,如果开发人员不做任何配置的情况下,优先使用这种方式。
-
服务器会根据客户端发送请求时提交在请求头中的信息,比如:”Accept:application/json“或"Accept:text/html"来决定最终响应什么格式数据;
2.3.2.1 操作示例
添加一个接口
@RestController
public class UserController {//localhost:8081/getUser@GetMapping("/getUser")public Object getUser(){return new User("mike",18);}}
正常调用,请求头不加任何参数默认得到的是json结构
如果在请求头指定响应的数据格式,如下,在Accept中指定是json
curl -H "Accept: application/json" localhost:8081/getUser
如果此时我们指定返回xml格式的数据,此时发现并不好使
curl -H "Accept: application/xml" localhost:8081/getUser
如果需要支持该怎么办呢?需要做下面的2步:
1)添加依赖jackson-dataformat-xml
-
可以将Java对象转为xml格式的数据
<dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId>
</dependency>
2)为实体类增加注解
在当前的User类上面添加注解 @JacksonXmlRootElement用于转换为xml
package com.congge.entity;import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@JacksonXmlRootElement
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {private String name;private int age;}
3)请求测试调用
指定为json
指定为xml
总结:
-
客户端请求的时候,通过在请求协议的请求头上面增加一个Accept字段,服务端接收到这个值之后,会根据这个参数值动态返回客户端要求的格式的数据;
2.3.3 通过请求参数
也可以在请求url中拼接指定的请求参数的方式实现,默认的请求参数名为format,格式如下:
http://xxx?format=json
仍然以上面的接口为例,测试一下这种方式的使用
curl http://localhost:8081/getUser?format=json
效果如下:
但是如果指定format为xml,发现并不生效
原因是springboot中在内容协商的处理上,优先使用Accept这种方式,所以如果你要使用format这种方式,还需在配置文件中增加下面的配置信息;
#使用format的方式完成内容协商,如果没有配置,默认采用Accept的方式实现
spring:mvc:contentnegotiation:favor-parameter: true#默认就叫format,也可以改为自定义的名称parameter-name: format
设置完成后再次重启服务测试,此时可以看到两种格式的数据都支持
三、SpringBoot 消息转换器介绍
在上面通过案例操作演示介绍了什么是spring框架的内容协商机制,简单来说就是,客户端需要什么样格式的数据,服务端就响应什么格式数据,事实上真的就那么简单吗?这背后框架做了什么呢?是不是有什么组件在这个转换的过程中起作用了呢?接下来就要详细介绍springmvc框架中对于内容协商的重要技术组件,即HttpMessageConvertor。
3.1 HttpMessageConvertor介绍
HttpMessageConvertor是一个接口,被翻译为HTTP消息转换器,即对HTTP消息进行转换,什么是HTTP消息呢?HTTP消息本质上就是浏览器向服务端发送请求时提交的数据,或者是服务器向浏览器响应的数据。而HttpMessageConvertor接口就是负责完成请求/响应时数据格式转换用的。
-
在springmvc框架中提供了很多种HttpMessageConvertor接口的实现类,不同的HTTP消息转换器具有不同的转换效果,使用的场景也有区别,有的是负责将Java对象转为JSON格式的数据,有的负责将Java对象转为XML格式的数据。
3.1.1 常用的HttpMessageConvertor
springmvc框架内置了一些常用的消息转换器,正是这些转换器完成了诸如上述json或xml格式的数据转换,下面介绍一些常用的框架内置的消息转换器:
-
FormHttpMessageConvertor
-
常用于处理提交表单数据时候使用的转换器;
-
-
MappingJackson2HttpMessageConvertor
-
客户端或浏览器提交JSON格式的数据转换为JAVA对象主要是由这个转换器处理,比如经常在POST请求接口上面添加的@RequestBody注解;
-
-
JaxbRootElementHttpMessageConvertor
-
将JAVA对象转为XML格式的数据通常由这个消息转换器完成;
-
-
StringHttpMessageConvertor
-
将String类型的的数据直接写入到响应中由这个转换器完成;
-
3.2 如何确定使用哪个消息转换器
有这么多的消息转换器,那么在具体使用的时候,框架是如何确定使用哪种类型的转换器的呢?
3.2.1 针对请求时的判断
请求时通常根据下面的条件来确定使用哪个消息转换器:
-
请求的Content-Type头信息
-
SpringMVC会检查Content-Type头信息,以确定请求体的数据格式,比如:application/json,application/xml...
-
-
方法参数类型
-
控制器方法中接收请求体的参数类型,比如POST请求中有@RequestBody注解;
-
3.2.2 针对响应时的判断
响应时通常根据以下条件来确定使用哪个消息转换器:
-
请求提交时,请求头上的Accept字段
-
Spring MVC 会检查客户端请求的 Accept 字段,以确定客户端期望的响应格式(例如 application/json、application/xml 等);
-
-
方法返回值的类型
-
控制器方法的返回值类型比如: @ResponseBody
-
@ResponseBody + 控制器方法的返回值是String,则使用StringHttpMessageConverter转换器。(将字符串直接写入响应体)
-
@ResponseBody + 控制器方法的返回值是Java对象,则使用MappingJackson2HttpMessageConverter转换器。(将java对象转换成json格式的字符串写入到响应体)
-
-
3.3 SpringMVC框架默认的消息转换器
SpringMVC框架自身已经内置了一些消息转换器,可以在启动的时候debug源码看到,主要包括下面6个
-
ByteArrayHttpMessageConverter
-
用于将字节数组(byte[])与HTTP消息体之间进行转换。这通常用于处理二进制数据,如图片或文件。
-
-
StringHttpMessageConverter
-
用于将字符串(String)与HTTP消息体之间进行转换。它支持多种字符集编码,能够处理纯文本内容。
-
-
ResourceHttpMessageConverter
-
用于将Spring的Resource对象与HTTP消息体之间进行转换。Resource是Spring中表示资源的接口,可以读取文件等资源。这个转换器对于下载文件或发送静态资源有用。
-
-
ResourceRegionHttpMessageConverter
-
用于处理资源的部分内容(即“Range”请求),特别是当客户端请求大文件的一部分时。这对于实现视频流媒体等功能很有用。
-
-
AllEncompassingFormHttpMessageConverter
-
用于处理表单,是一个比较全面的form消息转换器。处理标准的application/x-www-form-urlencoded格式的数据,以及包含文件上传的multipart/form-data格式的数据。
-
-
MappingJackson2HttpMessageConverter
-
使用Jackson库来序列化和反序列化JSON数据。可以将Java对象转换为JSON格式的字符串,反之亦然。
-
3.3.1 源码跟踪
入口类:WebMvcAutoConfiguration
-
WebMvcAutoConfiguration内部类EnableWebMvcConfiguration
-
EnableWebMvcConfiguration继承了DelegatingWebMvcConfiguration
-
DelegatingWebMvcConfiguration继承了WebMvcConfigurationSupport
DelegatingWebMvcConfiguration
继续进入到WebMvcConfigurationSupport
在这个类中,提供了一个方法 addDefaultHttpMessageConverters,在这个方法中,会将工程中的所有的消息转换器加进去。下面通过debug源码的方式跟进一下过程。
启动springboot工程后,进入该方法,此时messageConverters这个列表还是空的
从源码不难看出,方法中会new出几个内置的转换器加入到这个集合中
在上面的方法中,注意到会有一个判断的方法,比如:jackson2XmlPresent,它是如何判断的呢?其实在当前的类中,在静态代码块中维护了一个全局的布尔变量,工程在加载的时候,通过ClassUtils.isPresent方法,传入类的全路径,从而判断是否满足条件,满足,则在addDefaultHttpMessageConverters方法执行时候加入进去。
最后在这个方法执行完成的时候,列表中就添加了一些消息转换器
通过debug源码不难看出,在实际开发中,只要引入相关的依赖,让类路径存在某个类,则对应的消息转换器就会被加载。
四、自定义消息转换器
实际项目开发过程中,来自客户端的需求场景是很多的,当系统内置的转换器格式不能满足要求时,比如需要返回yaml格式的数据,或者其他定制化类型的数据时,此时就可以考虑自定义消息转换器。下面以yaml这种特殊格式的数据为例进行说明。
4.1 自定义yaml消息转换器
下面看具体的操作步骤。
4.1.1 引入如下的依赖
任何一个能够处理yaml格式数据的库都可以,这里选择使用jackson的库,因为它既可以处理json,xml,又可以处理yaml。
<dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-yaml</artifactId>
</dependency>
通过下面这段程序测试一下这个SDK的转换效果
import com.congge.entity.User;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;public class JavaYamlTest {public static void main(String[] args) throws JsonProcessingException {// 创建YAML工厂类YAMLFactory yamlFactory = new YAMLFactory().disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER); // 禁止使用文档头标记// 创建对象映射器ObjectMapper objectMapper = new ObjectMapper(yamlFactory);// 准备数据User user = new User("user01", 12);// 将数据转换成YAML格式String res = objectMapper.writeValueAsString(user);System.out.println(res);}}
运行可以看到能够正常转换
4.1.2 自定义yaml媒体类型
Springboot 默认支持xml和json两种媒体类型,如果要支持yaml格式的,需新增一个yaml媒体类型,在springboot的配置文件中进行如下配置:
spring:mvc:contentnegotiation:media-types:yaml: text/yaml
注意:
-
以上types后面的yaml是媒体类型的名字,名字可以自己修改,如果媒体类型起名为xyz,那么发送请求时的路径应该是这样的:http://localhost:8081/getUser?format=xyz
4.1.3 自定义HttpMessageConverter
编写一个类,比如:YamlHttpMessageConverter继承AbstractHttpMessageConverter,需要继承AbstractHttpMessageConverter这个类,参考下面的代码:
package com.congge.config;import com.congge.entity.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;import java.io.IOException;
import java.nio.charset.Charset;public class YamlHttpMessageConverter extends AbstractHttpMessageConverter<Object> {private ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory().disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER));/*** 将自定义的消息转换器 和 配置文件中自定义的媒体类型 text/yaml 进行绑定*/public YamlHttpMessageConverter() {super(new MediaType("text", "yaml", Charset.forName("UTF-8")));}/*** 用于指定消息转换器支持哪些类型的对象转换,比如这里指定User对象类型的数据进行转换* @param clazz* @return*/@Overrideprotected boolean supports(Class<?> clazz) {// 表示User类型的数据支持yaml,其他类型不支持return User.class.isAssignableFrom(clazz);}/*** 处理 @RequestBody(将提交的yaml格式数据转换为java对象)* @param clazz* @param inputMessage* @return* @throws IOException* @throws HttpMessageNotReadableException*/@Overrideprotected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {return null;}/*** 处理 @ResponseBody(将java对象转换为yaml格式的数据)* @param o* @param outputMessage* @throws IOException* @throws HttpMessageNotWritableException*/@Overrideprotected void writeInternal(Object o, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {this.objectMapper.writeValue(outputMessage.getBody(), o);// 注意:spring框架会自动关闭输出流,无需程序员手动释放。}
}
补充说明:
-
所有的消息转换器,包括自定义的,都需要实现HttpMessageConverter接口,或者继承AbstractHttpMessageConverter这个类,重写里面的核心方法。
4.1.4 配置消息转换器
重写WebMvcConfigurer接口的configureMessageConverters方法,将上面的自定义消息加入到全局的转换器列表中。
package com.congge.config;import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.util.List;@Configuration
public class ConverterWebConfig implements WebMvcConfigurer {@Overridepublic void configureMessageConverters(List<HttpMessageConverter<?>> converters) {converters.add(new YamlHttpMessageConverter());}}
4.1.5 测试与效果验证
启动工程,通过下面的curl命令再次测试,可以看到通过上面的自定义改造已经能够输出yaml格式的数据了
curl -H "Accept: text/yaml" localhost:8081/getUser
针对其他类型格式的转换器,也可以参照上面的步骤进行编写即可
五、写在文末
本文详细介绍了SpringBoot消息转换器的知识,并通过案例操作演示了如何进行自定义消息转换器的定制开发和使用,希望对看到的同学有用哦,本篇到此结束,感谢观看。
相关文章:
【微服务】SpringBoot 自定义消息转换器使用详解
目录 一、前言 二、SpringBoot 内容协商介绍 2.1 什么是内容协商 2.2 内容协商机制深入理解 2.2.1 内容协商产生的场景 2.3 内容协商实现的常用方式 2.3.1 前置准备 2.3.2 通过HTTP请求头 2.3.2.1 操作示例 2.3.3 通过请求参数 三、SpringBoot 消息转换器介绍 3.1 H…...
数据结构(哈希表(中)纯概念版)
前言 哈希表(Hash Table)是计算机科学中的一个基础而重要的数据结构,它广泛评估各种算法和系统中,尤其是在需要快速查找、插入和删除操作的场景中。由于其O( 1)的平均时间复杂度,存储表在性能要求较高的应用中表现得非…...
Node.js 工具:在 Windows 11 中配置 Node.js 的详细步骤
一、概述 记录时间 [2024-12-25] 本文讲述如何在 Windows 11 中进行 Node.js 工具的安装和配置。 以下是详细的步骤和说明。 二、安装 Node.js 1. 官网下载 通过官网,下载 Node.js,上面有好几种下载方式,文中下载的是 zip 压缩包。 如图&…...
工作流并行网关退回思路
问题描述 在设计工作流时遇到并行的流程,会出现并行流程的退回,这里记录下想到的解决思路,后续问题会记录在这里。 流程图 这里是一个简单的流程图: 并行退回思路 若是正常流程退回,流程是: 获取回退…...
C#数学相关开发性能优化方法
本文Github地址:CSharp-MathOptimization.md 华为公司的C语言编程规范在开头就强调了: 一般情况下,代码的可阅读性高于性能,只有确定性能是瓶颈时,才应该主动优化。 本文讲述的方法没有经过大项目和大公司的检验&…...
vulnhub jangow靶机
1.扫描靶机IP arp-scan -l如果扫不到靶机的话根据以下配置 启动时点击第二个 按回车 继续选择第二个 按e进入编辑 删除"recovery nomodeset" 在末尾添加"quiet splash rw init/bin/bash" Ctrlx 启动进入如下界面 passwd修改root密码 重启电脑登录root修…...
配置搜索无人机
升级ubuntu内核 https://www.bilibili.com/video/BV11X4y1h7qN/?spm_id_from333.337.search-card.all.click 进入四个内核文件并安装 sudo dpkg -i *.deb安装ROS,PX4,XTDrone,QGC https://blog.csdn.net/qq_45493236/article/details/13…...
2-6-1-1 QNX编程入门之进程和线程(四)
阅读前言 本文以QNX系统官方的文档英文原版资料“Getting Started with QNX Neutrino: A Guide for Realtime Programmers”为参考,翻译和逐句校对后,对在QNX操作系统下进行应用程序开发及进行资源管理器编写开发等方面,进行了深度整理&…...
Vue开发环境搭建上篇:安装NVM和NPM(cpnm、pnpm)
文章目录 引言I 安装NVM1.1 Windows系统安装NVM,实现Node.js多版本管理1.2 配置下载镜像1.3 NVM常用操作命令II NPM永久使用淘宝源安装 cnpm安装pnpm【推荐】see also: vscode常用插件引言 淘宝镜像:http://npm.taobao.org 和 http://registry.npm.taobao.org 已在 2022.06.3…...
2.微服务灰度发布落地实践(agent实现)
文章目录 前言java agent的介绍基础实现agent端 http服务实现agent端api接口 前言 据上一篇,设计方案的分析,综合考虑,最终决定,客户端采用agent方案实现,具本原因不再赘述, 感觉兴趣的小伙伴可以回头了解一下.该篇主…...
网络安全专业术语
网络安全专有名词详解 1.肉鸡 被黑客操控的终端设备(电脑、服务器、移动设备等等),黑客可以随心所欲的操作这些终端设备而不会被发觉。 2.木马 表面上伪装成正常的程序,但是当这些程序运行时候就会获取整个系统的控制权限&#…...
SpringMVC核心、两种视图解析方法、过滤器拦截器 “ / “ 的意义
SpringMVC的执行流程 1. Spring MVC 的视图解析机制 Spring MVC 的核心职责之一是将数据绑定到视图并呈现给用户。它通过 视图解析器(View Resolver) 来将逻辑视图名称解析为具体的视图文件(如 HTML、JSP)。 核心流程 Controlle…...
ubuntu快速入门
1.进入某个文件夹 cd workspace/2.tab自动补全 3.列出当前文件夹所有文件 ls列出所有文件包括隐藏文件 ls -a 4.创建文件夹 mkdir linuxLearn 5.创建文件 gedit command.sh在commmand.sh键入 echo hello echo hi? echo how are you? PS:touch hello.txt(也可以创建新…...
HarmonyOS NEXT应用开发实战:一分钟写一个网络接口,JsonFormat插件推荐
在开发鸿蒙操作系统应用时,网络接口的实现往往是一个繁琐且重复的过程。为了提高开发效率,坚果派(nutpi.net)特别推出了一个非常实用的插件——JsonFormat。这款插件的主要功能是将JSON格式的数据直接转换为arkts的结构定义,让我们在编写接口…...
光谱相机与普通相机的区别
一、成像目的 普通相机:主要目的是记录物体的外观形态,生成人眼可见的、直观的二维图像,重点在于还原物体的形状、颜色和纹理等视觉特征,以供人们进行观赏、记录场景或人物等用途。例如,拍摄旅游风景照片、人物肖像等…...
贝叶斯神经网络(Bayesian Neural Network)
最近在研究贝叶斯神经网络,一些概念一直搞不清楚,这里整理一下相关内容,方便以后查阅。 贝叶斯神经网络(Bayesian Neural Network) 贝叶斯神经网络(Bayesian Neural Network)1. BNN 的核心思想2. BNN 的优化目标3. BNN 的结构与特点4. BNN 的训练过程5. BNN 的优缺点6. …...
使用FFmpeg进行拉流和推流操作
FFmpeg是一款强大的多媒体处理工具,可以用于视频的录制、转换、推流和拉流等操作。下面将详细介绍如何使用FFmpeg进行拉流和推流操作。 1. FFmpeg推流操作 推流是将本地的音视频流推送到流媒体服务器上,例如主播将本地电脑上的画面推流到直播平台的流媒…...
flutter插件开发-ios
flutter插件开发是一个重要的技能,拓展flutter与原生的通信,将一些公用的东西封装,给不同的项目使用。 阅读前置: flutter基本通道调用 objective-c基础语法 ios项目基础知识 目录 1、创建一个插件项目2、项目结构3、编写原生代码…...
【代码随想录|完全背包问题】
518.零钱兑换|| 题目链接:518. 零钱兑换 II - 力扣(LeetCode) 这里求的是组合数,就是不强调元素排列的顺序,211和121是同一个数那种,要先遍历物品,这样的话我算出来的每个值才是按顺序121&…...
xss csrf怎么预防?
一、XSS(跨站脚本攻击)预防 XSS 是指攻击者向目标网站注入恶意脚本,从而在用户浏览器中执行。 1. 输入过滤 清理用户输入: 拦截或清理HTML特殊字符(如 <, >, , ", &)。使用安全库&#x…...
黑神话悟空游戏鼠标光标使用教程与下载
效果图: 鼠标光标特点 这套鼠标光标的设计灵感来源于《黑神话:悟空》游戏中的角色和元素,具有以下特点: • 主题鲜明:光标设计紧扣游戏主题,采用了游戏中的元素,让玩家在使用电脑时也能感受到…...
<数据集>芝麻作物和杂草识别数据集<目标检测>
数据集下载链接 <数据集>芝麻作物和杂草识别数据集<目标检测>https://download.csdn.net/download/qq_53332949/90181548数据集格式:VOCYOLO格式 图片数量:1300张 标注数量(xml文件个数):130…...
实测数据处理(CS算法处理:可斜视)——SAR成像算法系列(十一)
系列文章目录 《SAR学习笔记-SAR成像算法系列(一)》 《线性调频变标算法(CSA)-SAR成像算法系列(四)》 文章目录 前言 一、算法流程 1.1、回波信号生成 1.2、CS处理 1.3、距离脉压 1.4、方位脉压 1.5…...
【强化学习入门笔记】 2.4 时序差分算法
本系列为学习赵世钰老师的《强化学习的数学原理》所作的学习笔记. 本节我们将介绍强化学习中的蒙特卡洛方法. 2.4.1 Robbins-Monro算法 Robbins-Monro算法是一种随机近似方法,通过迭代的方式求解非线性方程。 假设我们要求解: g ( w ) 0 g(w)0 g(w)0, 但是我们…...
Scrapy数据解析+保存数据
Scrapy数据解析保存数据 目录 1.数据解析 2.基于item存放数据并提交给管道 3.用txt文件来保存数据 今天我们需要爬取B站数据并保存到txt文件里面。 我们先打开B站, 然后点击热门, 进去之后再点击排行榜: 我们打开F12后, 可以看到, 我们想要的请求, 轻而易举的就可以拿到(…...
Redis--缓存穿透、击穿、雪崩以及预热问题(面试高频问题!)
缓存穿透、击穿、雪崩以及预热问题 如何解决缓存穿透?方案一:缓存空对象方案二:布隆过滤器什么是布隆过滤器?优缺点 方案三:接口限流 如何解决缓存击穿问题?方案一:分布式锁方案一改进成双重判定…...
【Python高级353】python实现多线程版本的TCP服务器
前面学了了套接字编程、tcp服务端客户端开发、面向对象版的服务端客户端、带有端口复用的服务端。 这里使用多线程开发多任务版的服务端 多任务版本的TCP服务器 来一个客户,就为其创建一个线程 import socket import threadingclass WebServer:# 3、定义一个__ini…...
【Pandas】pandas Series to_period
Pandas2.2 Series Conversion 方法描述Series.astype用于将Series对象的数据类型转换为指定类型的方法Series.convert_dtypes用于将 Series 对象的数据类型智能地转换为最佳可能的数据类型的方法Series.infer_objects用于尝试推断 Series 中对象(object࿰…...
深度学习领域车辆识别与跟踪
深度学习中车辆识别是一个广泛应用的领域,它涵盖了从车辆检测到车型识别的多个方面。以下是对深度学习中车辆识别与车辆相关内容的详细探讨: 一、车辆检测 车辆检测是车辆识别中的基础任务,其目标是在图像或视频中准确地定位出车辆的位置。…...
数学建模 绘图 图表 可视化(2)
文章目录 前言柱形图条形图克利夫兰点图系列坡度图南丁格尔玫瑰图径向柱图极坐标图词云图总结参考资料 前言 承接上期 数学建模 绘图 图表 可视化(1)的总体描述,这期我们继续跟随《Python 数据可视化之美 专业图表绘制指南》步伐来学习其中l…...
vue源码分析(十)—— 生命周期
文章目录 前言一、关键方法 callHook二、详细的钩子函数说明1.beforeCreate和create2.beforeMount & mounted注意点组件(非根组件)的渲染节点(1)invokeInsertHook函数(2)insert方法(3&#…...
[创业之路-222]:波士顿矩阵与GE矩阵在业务组合选中作用、优缺点比较
目录 一、波士顿矩阵 1、基本原理 2、各象限产品的定义及战略对策 3、应用 4、优点与局限性 二、技术成熟度模型与产品生命周期模型的配对 1、技术成熟度模型 2、产品生命周期模型 3、技术成熟度模型与产品生命周期模型的配对 三、产品生命周期与产品类型的对应关系 …...
# 【超全面了解鸿蒙生命周期】-生命周期补充
【超全面了解鸿蒙生命周期】-生命周期补充 鸿蒙所有的生命周期函数梳理 文章目录 【超全面了解鸿蒙生命周期】-生命周期补充前言一、AbilityStage的生命周期二、ExtensionAbility卡片生命周期三、Web组件常用生命周期 前言 本文是继之前写的生命周期函数梳理的进一步补充&…...
sentinel-请求限流、线程隔离、本地回调、熔断
请求限流:控制QPS来达到限流的目的 线程隔离:控制线程数量来达到限流的目录 本地回调:当线程被限流、隔离、熔断之后、就不会发起远程调用、而是使用本地已经准备好的回调去提醒用户 熔断:熔断也叫断路器,当失败、或者…...
unplugin-vue-router 的基本使用
1. 前言 在Vue3开发过程中,每次创建新的页面都需要注册路由,需要在src/router.ts中新增页面的路径,并将URL路径映射到组件中,如下所示: import { createMemoryHistory, createRouter } from vue-routerimport HomePage…...
[Leetcode] 最大子数组和 [击败99%的解法]
解法1: 暴力解法 遍历每个元素,从它当前位置一直加到最后,然后用一个最大值来记录全局最大值。 代码如下: class Solution {public int maxSubArray(int[] nums) {long sum, max nums[len-1];for (int i0; i<nums.length;…...
SSRF服务端请求Gopher伪协议白盒测试
前言 是什么SSRF? 这个简单点说就是 服务端的请求伪造 就是这个如果是个 请求图片的网站 他的目的是请求外部其他网站的 图片 但是 SSRF指的是让他请求本地的图片 再展示出来 请求的是他的服务器上的图片 SSRF(Server-Side Request Forgery:服务器端请求伪造) …...
[2029].第6-06节:MyISAM引擎中的索引与 InnoDB引擎中的索引对比
所有博客大纲 后端学习大纲 MySQL学习大纲 1.MyISAM索引: 1.1.B树索引适用存储引擎: 1.B树索引适用存储引擎如下表所示: 2.即使多个存储引擎都支持同一种类型的B树索引,但它们的实现原理也是不同的 Innodb和MyISAM默认的索引是B…...
WOFOST作物模型(3):(本地化校准)优化PCSE模型中的参数
目录 一、准备自己的LAI观测数据二、优化参数三、损失函数四、NLOPT优化五、优化结果可视化一、准备自己的LAI观测数据 在进行田间实测后,得到自己的LAI观测数据 在程序这个地方输入自己的LAI采样日期和观测值 二、优化参数 这里主要选择了TDWI(Total Dry Weight at ger…...
如何修改pip全局缓存位置和全局安装包存放路径
使用场景: 在默认情况下,pip 会将安装的包存放在 Python 环境的 site-packages 目录下,会使用到系统盘的内存。 当遇到系统盘的内存很小的时候,需要修改pip的全局缓存位置和全局安装包存放路径,可以极大的节省系统盘内存 详细步骤ÿ…...
ZooKeeper注册中心实现
具体步骤 安装ZooKeeper(启动端口占用,2181:客户端,8080:管理端)引入客户端依赖实现注册中心接口SPI补充ZooKeeper注册中心 引入依赖 <!-- zookeeper --> <dependency><groupId>org.a…...
PyTorch快速入门教程【小土堆】之DataLoader的使用
视频地址DataLoader的使用_哔哩哔哩_bilibili dataset数据集,相当于一副扑克,dataloader数据加载器相当于我们的手,选择摸几张牌,怎么摸牌 import torchvision# 准备的测试数据集 from torch.utils.data import DataLoader from …...
khadas edge2安装ubuntu22.04与ubuntu20.04 docker镜像
khadas edge2安装ubuntu22.04与ubuntu20.04 docker镜像 一、资源准备1.1 镜像文件1.2 刷机工具1.3 ubuntu20.04 docker镜像(具备demon无人机所需各种驱动) 二、开始刷机(安装ubuntu22.04系统)2.1 进入刷机状态2.2 刷机 三、docker…...
大数据面试笔试宝典之Kafka面试
1.Kafka 如何实现高吞吐率 Kafka 如何实现高吞吐率? 参考答案: 1)顺序读写...
新手SEO入门指南如何有效提升网站排名
内容概要 在进行搜索引擎优化(SEO)时,了解基本概念与重要性是首要步骤。SEO不仅仅是提升网站在搜索引擎中排名的手段,它还关乎用户体验和网站内容的质量。随着互联网的发展,越来越多的人意识到优秀的SEO策略能带来持续…...
【Redis】:初识Redis
1.1 盛赞 Redis Redis 是⼀种基于键值对(key-value)的 NoSQL 数据库,与很多键值对数据库不同的是,Redis 中的值可以是由 string(字符串)、hash(哈希)、list(列表…...
C-5 B样条曲线
C-5 B样条曲线 N i , 0 ( u ) { 1 , u i ≤ u < u i 1 0 , o t h e r s N_{i,0}(u)\left\{\begin{matrix} 1 , \quad u_i\le u <u_{i1} \\0 ,\quad others \qquad \quad\end{matrix}\right. Ni,0(u){1,ui≤u<ui10,others N i , p ( u ) u − u i u i p −…...
python安装
python安装 1.下载2.安装3.验证安装成功 1.下载 (1)下载网址:https://www.python.org/downloads/windows/ 进入后稍等一会,比较慢 (2)选择版本 2.安装 (1)双击或者以管理员身份运…...
游戏引擎学习第65天
回顾我们在模拟区域更改方面的进展 目前我们正在进行游戏的架构调整,目标是建立一个引擎架构。我们正在实施的一个关键变化是引入模拟区域的概念,这样我们可以创建非常大的游戏世界,而这些世界的跨度不必受限于单个浮点变量。 通过这种方式…...
代码随想录算法训练营第十六天-二叉树-513.找树左下角的值
左下角不是以为的左下角,而最后一层最左侧的节点也是就是说一个右叶子节点,也可能是最左下角,当然是在其左侧再无其它同级节点看视频讲解使用的递归与回溯方法,自己是完全想不到的,对这道题解法完全是脑袋空空 #inclu…...