【微服务】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消息转换器的知识,并通过案例操作演示了如何进行自定义消息转换器的定制开发和使用,希望对看到的同学有用哦,本篇到此结束,感谢观看。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/64389.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入理解Composer自动加载机制

Composer是PHP生态系统中最常用的依赖管理工具之一&#xff0c;它不仅能够帮助开发者管理项目的依赖关系&#xff0c;还能够自动加载这些依赖项。自动加载机制是Composer的核心功能之一&#xff0c;通过自动加载&#xff0c;开发者可以在运行时按需加载所需的类和文件&#xff…

【游戏设计原理】35 - 委员会设计

一、 分析并总结 核心内容 定义&#xff1a;委员会设计&#xff08;Design by Committee&#xff09;是指游戏开发团队通过集体协作完成设计&#xff0c;这种模式结合了多样化的创意和个体专长&#xff0c;但也可能因缺乏一致性而导致设计的混乱。优势&#xff1a;多样性带来…

【Java】IO流练习

IO流练习 题干&#xff1a; 根据指定要求&#xff0c;完成电话记录、 注册、登录 注册 题干&#xff1a; 完成【注册】功能&#xff1a; 要求&#xff1a; 用户输入用户名、密码存入users.txt文件中 若users.txt文件不存在&#xff0c;创建该文件若users.txt文件存在 输入…

内网学习:工作组用户与权限

目录 一、本地用户组介绍本地工作组介绍用户与组的关系 二、四种用户类型及权限比较本地系统最高权限&#xff08;System账户&#xff09;特性Administrator与System账户的区别 本地最高管理员&#xff08;Administrator用户&#xff09;特性 本地普通管理员特性 本地普通用户特…

SpringMVC核心、两种视图解析方法、过滤器拦截器 “ / “ 的意义

SpringMVC的执行流程 1. Spring MVC 的视图解析机制 Spring MVC 的核心职责之一是将数据绑定到视图并呈现给用户。它通过 视图解析器&#xff08;View Resolver&#xff09; 来将逻辑视图名称解析为具体的视图文件&#xff08;如 HTML、JSP&#xff09;。 核心流程 Controlle…

抽象类和接口的区别是什么?

抽象类和接口在编程中都是用来定义对象的公共行为的重要概念&#xff0c;但两者之间存在显著的区别。以下是对抽象类和接口的详细比较&#xff1a; 一、定义与关键字 抽象类&#xff1a;使用abstract关键字定义&#xff0c;表示该类是抽象的&#xff0c;不能被实例化。抽象类…

html+css+js网页设计 美食 美拾9个页面

htmlcssjs网页设计 美食 美拾9个页面 网页作品代码简单&#xff0c;可使用任意HTML辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取源码 1&#xff0…

Linux下PostgreSQL-12.0安装部署详细步骤

一、安装环境 postgresql-12.0 CentOS-7.6 注意&#xff1a;确认linux系统可以正常连接网络&#xff0c;因为在后面需要添加依赖包。 二、pg数据库安装包下载 下载地址&#xff1a;PostgreSQL: File Browser 选择要安装的版本进行下载&#xff1a; 三、安装依赖包 在要安…

『VUE』vue-quill-editor设置内容不可编辑(详细图文注释)

目录 预览思路调用代码借助Props添加isDisable属性控制 是否内容可编辑总结 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 预览 思路 禁用焦点事件和内容改变事件 调用代码 <quillEditorclass"editor":class"…

python 和go 语法对比

Python 和 Go 是两种设计哲学和应用场景有所不同的编程语言&#xff0c;它们在语法、类型系统、并发模型等方面存在显著差异。以下是 Python 和 Go 语法特点的详细对比&#xff1a; 语法简洁性与结构 Python 的语法以其简洁易读而著称。它使用缩进来表示代码块的层次结构&…

我们来学activiti -- bpmn

bpmn 题记bpmn结余 题记 在《Activiti很难学》提到学习知识点需要面对的思想钢印问题 按常见步骤&#xff0c;先展示下官方的客套话 BPMN&#xff08;Business Process Model and Notation&#xff09;是一种业务流程建模符号&#xff0c; 它是一种图形化的语言&#xff0c;用…

【MuJoCo和PhysX】

MuJoCo 与 Unity 的 PhysX 引擎的主要区别 应用领域&#xff1a; MuJoCo&#xff1a;主要用于机器人学、强化学习、生物力学等领域&#xff0c;擅长处理多自由度、复杂动力学问题&#xff0c;尤其适合进行高精度的物理仿真。 Unity PhysX&#xff1a;主要用于游戏开发、虚拟现…

LeetCode:257. 二叉树的所有路径

跟着carl学算法&#xff0c;本系列博客仅做个人记录&#xff0c;建议大家都去看carl本人的博客&#xff0c;写的真的很好的&#xff01; 代码随想录 LeetCode&#xff1a;257. 二叉树的所有路径 给你一个二叉树的根节点 root &#xff0c;按 任意顺序 &#xff0c;返回所有从根…

十二月第五周python

第一个程序&#xff0c;熟悉转换器&#xff0c;把加法计算器变成exe# // 1,制作加法计算器&#xff0c; # 输入两个数字得到相加结果并输出aint(input("输入数字&#xff1a;"))#int()是把输入的内容转换成整数&#xff0c; bint(input("输入数字&#xff1a;&…

FFmpeg 的常用API

FFmpeg 的常用API 附录&#xff1a;FFmpeg库介绍 库介绍libavcodec音视频编解码核心库编码 (avcodec_send_frame, avcodec_receive_packet)。解码 (avcodec_send_packet, avcodec_receive_frame)。libavformat提供了音视频流的解析和封装功能&#xff0c;多种多媒体封装格式&…

关于最新MySQL9.0.1版本zip自配(通用)版下载、安装、环境配置

一、下载 从MySQL官网进行下载MySQL最新版本&#xff0c;滑到页面最下面点击社区免费版&#xff0c;&#xff08;不是企业版&#xff09; 点击完成后选择自己想要下载的版本&#xff0c;选择下载zip压缩&#xff0c;不用debug和其他的东西。 下载完成后进入解压&#xff0c;注…

vulnhub靶场 Empire LupinOne

使用命令查看靶机ip,访问ip arp-scan -l 使用御剑扫描一下子域名&#xff0c;但是没有获取到什么有用的信息 这是一个Apache文档&#xff0c;没有什么用 紧接着我们尝试暴力破解&#xff0c;这里推荐使用ffuf工具暴力破解目录&#xff0c;kali自带的ffuf扫描速度贼快 参数解释…

Kubernetes# Helm工具使用

目录 概念 核心组件 Helm客户端 Tiller Chart Repository Release Helm安装 Helm使用 创建Helm Chart 定义Chart元数据 定义Template模板 定义values参数 打包和部署 Helm Chart 推送到远程仓库 Helm常用命令 概念 Helm 是一个 Kubernetes 的包管理工具&#…

Mirror网络框架-从入门到精通之Mirror简介

前言 在现代游戏开发中&#xff0c;网络功能日益成为提升游戏体验的关键组成部分。Mirror是一个用于Unity的开源网络框架&#xff0c;专为多人游戏开发设计。它使得开发者能够轻松实现网络连接、数据同步和游戏状态管理。本文将深入介绍Mirror的基本概念、如何与其他网络框架进…

Yocto 项目中的交叉编译:原理与实例

Yocto 项目是一个强大的工具集&#xff0c;它专注于为嵌入式系统生成定制的 Linux 发行版。交叉编译在 Yocto 项目中扮演着核心角色&#xff0c;它使得开发者能够在功能强大的宿主机上构建适用于资源受限目标设备的软件系统。这篇文章将从运行原理、实际案例和工具链组成等角度…