对于最新的稳定版本,请使用 Spring Framework 6.2.0spring-doc.cadn.net.cn

响应式核心

spring-webmodule 包含对反应式 Web 的以下基本支持 应用:spring-doc.cadn.net.cn

HttpHandler

HttpHandler 是一个简单的协定,具有处理请求和响应的单一方法。是的 有意最小化,其主要且唯一目的是成为最小抽象 通过不同的 HTTP 服务器 API 进行。spring-doc.cadn.net.cn

下表描述了支持的服务器 API:spring-doc.cadn.net.cn

服务器名称 使用的服务器 API Reactive Streams 支持

spring-doc.cadn.net.cn

Netty APIspring-doc.cadn.net.cn

Reactor Nettyspring-doc.cadn.net.cn

Undertowspring-doc.cadn.net.cn

Undertow APIspring-doc.cadn.net.cn

spring-web: Undertow 到 Reactive Streams 桥spring-doc.cadn.net.cn

Tomcatspring-doc.cadn.net.cn

Servlet 非阻塞 I/O;Tomcat API 读取和写入 ByteBuffers 与 byte[]spring-doc.cadn.net.cn

spring-web:Servlet 非阻塞 I/O 到 Reactive Streams 桥spring-doc.cadn.net.cn

Jettyspring-doc.cadn.net.cn

Servlet 非阻塞 I/O;Jetty API 写入 ByteBuffers 与 byte[]spring-doc.cadn.net.cn

spring-web:Servlet 非阻塞 I/O 到 Reactive Streams 桥spring-doc.cadn.net.cn

Servlet 容器spring-doc.cadn.net.cn

Servlet 非阻塞 I/Ospring-doc.cadn.net.cn

spring-web:Servlet 非阻塞 I/O 到 Reactive Streams 桥spring-doc.cadn.net.cn

下表描述了服务器依赖项(另请参阅支持的版本):spring-doc.cadn.net.cn

服务器名称 组 ID 项目名称

Reactor Nettyspring-doc.cadn.net.cn

io.projectreactor.nettyspring-doc.cadn.net.cn

反应器-NETTYspring-doc.cadn.net.cn

Undertowspring-doc.cadn.net.cn

io.undertowspring-doc.cadn.net.cn

undertow-corespring-doc.cadn.net.cn

Tomcatspring-doc.cadn.net.cn

org.apache.tomcat.embedspring-doc.cadn.net.cn

tomcat-embed-corespring-doc.cadn.net.cn

Jettyspring-doc.cadn.net.cn

org.eclipse.jetty 网站spring-doc.cadn.net.cn

jetty 服务器、jetty-servletspring-doc.cadn.net.cn

下面的代码片段显示了如何使用HttpHandleradapters 的 API 中:spring-doc.cadn.net.cn

Reactor Nettyspring-doc.cadn.net.cn

HttpHandler handler = ...
ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(handler);
HttpServer.create().host(host).port(port).handle(adapter).bindNow();
val handler: HttpHandler = ...
val adapter = ReactorHttpHandlerAdapter(handler)
HttpServer.create().host(host).port(port).handle(adapter).bindNow()
HttpHandler handler = ...
UndertowHttpHandlerAdapter adapter = new UndertowHttpHandlerAdapter(handler);
Undertow server = Undertow.builder().addHttpListener(port, host).setHandler(adapter).build();
server.start();
val handler: HttpHandler = ...
val adapter = UndertowHttpHandlerAdapter(handler)
val server = Undertow.builder().addHttpListener(port, host).setHandler(adapter).build()
server.start()
HttpHandler handler = ...
Servlet servlet = new TomcatHttpHandlerAdapter(handler);

Tomcat server = new Tomcat();
File base = new File(System.getProperty("java.io.tmpdir"));
Context rootContext = server.addContext("", base.getAbsolutePath());
Tomcat.addServlet(rootContext, "main", servlet);
rootContext.addServletMappingDecoded("/", "main");
server.setHost(host);
server.setPort(port);
server.start();
val handler: HttpHandler = ...
val servlet = TomcatHttpHandlerAdapter(handler)

val server = Tomcat()
val base = File(System.getProperty("java.io.tmpdir"))
val rootContext = server.addContext("", base.absolutePath)
Tomcat.addServlet(rootContext, "main", servlet)
rootContext.addServletMappingDecoded("/", "main")
server.host = host
server.setPort(port)
server.start()
HttpHandler handler = ...
Servlet servlet = new JettyHttpHandlerAdapter(handler);

Server server = new Server();
ServletContextHandler contextHandler = new ServletContextHandler(server, "");
contextHandler.addServlet(new ServletHolder(servlet), "/");
contextHandler.start();

ServerConnector connector = new ServerConnector(server);
connector.setHost(host);
connector.setPort(port);
server.addConnector(connector);
server.start();
val handler: HttpHandler = ...
val servlet = JettyHttpHandlerAdapter(handler)

val server = Server()
val contextHandler = ServletContextHandler(server, "")
contextHandler.addServlet(ServletHolder(servlet), "/")
contextHandler.start();

val connector = ServerConnector(server)
connector.host = host
connector.port = port
server.addConnector(connector)
server.start()

Servlet 容器spring-doc.cadn.net.cn

要作为 WAR 部署到任何 Servlet 容器,您可以扩展并包含AbstractReactiveWebInitializer在战争中。该类将HttpHandlerServletHttpHandlerAdapter和寄存器 那作为一个Servlet.spring-doc.cadn.net.cn

WebHandler应用程序接口

org.springframework.web.server软件包构建在HttpHandler合同 提供通用的 Web API,用于通过多个WebExceptionHandler倍数WebFilter和单个WebHandler元件。链条可以 与WebHttpHandlerBuilder通过简单地指向 SpringApplicationContext自动检测组件,和/或通过注册组件 与构建器。spring-doc.cadn.net.cn

HttpHandler有一个简单的目标,即抽象出不同 HTTP 服务器的使用,WebHandlerAPI 旨在提供 Web 应用程序中常用的更广泛的功能集 如:spring-doc.cadn.net.cn

特殊 bean 类型

下表列出了WebHttpHandlerBuilder可以在 Spring ApplicationContext,或者可以直接使用它注册:spring-doc.cadn.net.cn

Bean 名称 Bean 类型 计数 描述

<任意>spring-doc.cadn.net.cn

WebExceptionHandlerspring-doc.cadn.net.cn

0..Nspring-doc.cadn.net.cn

为来自链的异常提供处理WebFilterinstances 和目标WebHandler.有关更多详细信息,请参阅 异常spring-doc.cadn.net.cn

<任意>spring-doc.cadn.net.cn

WebFilterspring-doc.cadn.net.cn

0..Nspring-doc.cadn.net.cn

将拦截样式逻辑应用于过滤器链的其余部分之前和之后,并且 目标WebHandler.有关更多详细信息,请参阅筛选器spring-doc.cadn.net.cn

webHandlerspring-doc.cadn.net.cn

WebHandlerspring-doc.cadn.net.cn

1spring-doc.cadn.net.cn

请求的处理程序。spring-doc.cadn.net.cn

webSessionManagerspring-doc.cadn.net.cn

WebSessionManagerspring-doc.cadn.net.cn

0..1spring-doc.cadn.net.cn

的经理WebSession通过ServerWebExchange.DefaultWebSessionManager默认情况下。spring-doc.cadn.net.cn

serverCodecConfigurerspring-doc.cadn.net.cn

ServerCodecConfigurerspring-doc.cadn.net.cn

0..1spring-doc.cadn.net.cn

要访问HttpMessageReader实例来解析表单数据和多部分数据,然后是 通过 上的 方法公开ServerWebExchange.ServerCodecConfigurer.create()默认情况下。spring-doc.cadn.net.cn

localeContextResolverspring-doc.cadn.net.cn

LocaleContextResolverspring-doc.cadn.net.cn

0..1spring-doc.cadn.net.cn

的解析程序LocaleContext通过ServerWebExchange.AcceptHeaderLocaleContextResolver默认情况下。spring-doc.cadn.net.cn

forwardedHeaderTransformerspring-doc.cadn.net.cn

ForwardedHeaderTransformerspring-doc.cadn.net.cn

0..1spring-doc.cadn.net.cn

用于处理转发类型的标头,可以通过提取和删除它们,或者仅删除它们。 默认情况下不使用。spring-doc.cadn.net.cn

表单数据

ServerWebExchange公开以下用于访问表单数据的方法:spring-doc.cadn.net.cn

Mono<MultiValueMap<String, String>> getFormData();
suspend fun getFormData(): MultiValueMap<String, String>

DefaultServerWebExchange使用配置的HttpMessageReader解析表单数据 (application/x-www-form-urlencoded) 转换为MultiValueMap.默认情况下,FormHttpMessageReader配置为供ServerCodecConfigurer豆 (请参阅 Web 处理程序 API)。spring-doc.cadn.net.cn

多部分数据

ServerWebExchange公开以下用于访问分段数据的方法:spring-doc.cadn.net.cn

Mono<MultiValueMap<String, Part>> getMultipartData();
suspend fun getMultipartData(): MultiValueMap<String, Part>

DefaultServerWebExchange使用配置的HttpMessageReader<MultiValueMap<String, Part>>解析multipart/form-data,multipart/mixedmultipart/relatedcontent 转换为MultiValueMap. 默认情况下,这是DefaultPartHttpMessageReader,它没有任何第三方 依赖。 或者,SynchronossPartHttpMessageReader,它基于 Synchronoss NIO Multipart 库。 两者都是通过ServerCodecConfigurer豆 (请参阅 Web 处理程序 API)。spring-doc.cadn.net.cn

要以流式处理方式解析多部分数据,您可以使用Flux<PartEvent>PartEventHttpMessageReader而不是使用@RequestPart,正如这意味着Map类访问 按名称分配给各个部分,因此需要完整解析多个部分数据。 相比之下,您可以使用@RequestBody将内容解码为Flux<PartEvent>没有 collecting 到MultiValueMap.spring-doc.cadn.net.cn

请求头转发

当请求通过负载均衡器等代理时,主机、端口和 方案可能会更改,这使得创建指向正确 Host、Port 和 Scheme。spring-doc.cadn.net.cn

RFC 7239 定义了ForwardedHTTP 标头 代理可用于提供有关原始请求的信息。spring-doc.cadn.net.cn

非标准标头

还有其他非标准标头,包括X-Forwarded-Host,X-Forwarded-Port,X-Forwarded-Proto,X-Forwarded-SslX-Forwarded-Prefix.spring-doc.cadn.net.cn

X-转发主机

虽然不是标准的,X-Forwarded-Host: <host>是事实上的标准标头,用于将原始主机传送到 downstream server 的例如,如果example.com/resource将发送到 一个代理,它将请求转发到localhost:8080/resource,则X-Forwarded-Host: example.com可以发送通知服务器原始主机是example.com.spring-doc.cadn.net.cn

X 转发端口

虽然不是标准的,X-Forwarded-Port: <port>是事实上的标准标头,用于 将原始端口传送到下游服务器。例如,如果example.com/resource将发送到代理,该代理将请求转发到localhost:8080/resource,则X-Forwarded-Port: 443可以发送 通知服务器原始端口为443.spring-doc.cadn.net.cn

X 转发原型

虽然不是标准的,X-Forwarded-Proto: (https|http)是用于通信原始协议(例如 HTTPS / HTTPS)的事实标准标头 到下游服务器。例如,如果example.com/resource将发送到 一个代理,它将请求转发到localhost:8080/resource,则X-Forwarded-Proto: https可以发送通知服务器原来的协议是https.spring-doc.cadn.net.cn

X-转发 SSL

虽然不是标准的,X-Forwarded-Ssl: (on|off)是事实上的标准标头,用于传达 原始协议(例如 HTTPS / HTTPS)到下游服务器。例如,如果example.com/resource将发送到代理,该代理将请求转发到localhost:8080/resource,则X-Forwarded-Ssl: on通知服务器 最初的协议是https.spring-doc.cadn.net.cn

X 转发前缀

虽然不是标准的,X-Forwarded-Prefix: <prefix>是事实上的标准标头,用于将原始 URL 路径前缀传达给 downstream server 的spring-doc.cadn.net.cn

用途X-Forwarded-Prefix可能因部署方案而异,并且需要灵活地 允许替换、删除或预置目标服务器的路径前缀。spring-doc.cadn.net.cn

场景 1:覆盖路径前缀spring-doc.cadn.net.cn

https://example.com/api/{path} -> http://localhost:8080/app1/{path}

前缀是 capture 组之前的路径的开头{path}.对于代理, 前缀为/api而对于服务器,前缀为/app1.在这种情况下,代理 可以发送X-Forwarded-Prefix: /api具有原始前缀/api覆盖 服务器前缀/app1.spring-doc.cadn.net.cn

方案 2:删除路径前缀spring-doc.cadn.net.cn

有时,应用程序可能希望删除前缀。例如,考虑 以下代理到服务器的映射:spring-doc.cadn.net.cn

https://app1.example.com/{path} -> http://localhost:8080/app1/{path}
https://app2.example.com/{path} -> http://localhost:8080/app2/{path}

代理没有前缀,而应用程序app1app2具有路径前缀/app1/app2分别。代理可以发送X-Forwarded-Prefix: 自 让空前缀覆盖服务器前缀/app1/app2.spring-doc.cadn.net.cn

此部署方案的一个常见情况是许可证按 production application server 部署多个应用程序,并且最好为每个 server 来降低费用。另一个原因是在同一台服务器上运行更多应用程序 order 共享服务器运行所需的资源。spring-doc.cadn.net.cn

在这些情况下,应用程序需要一个非空的上下文根,因为有多个 应用程序。但是,这在 公共 API,应用程序可以在其中使用不同的子域,从而提供优势 如:spring-doc.cadn.net.cn

方案 3:插入路径前缀spring-doc.cadn.net.cn

在其他情况下,可能需要在前面加上前缀。例如,考虑 以下代理到服务器的映射:spring-doc.cadn.net.cn

https://example.com/api/app1/{path} -> http://localhost:8080/app1/{path}

在这种情况下,代理的前缀为/api/app1服务器具有前缀/app1.代理可以发送X-Forwarded-Prefix: /api/app1具有原始前缀/api/app1覆盖服务器前缀/app1.spring-doc.cadn.net.cn

转发标头转换器

ForwardedHeaderTransformer是一个组件,用于修改 请求,然后删除这些标头。如果您声明 it 作为名为forwardedHeaderTransformer,它将被检测并使用。spring-doc.cadn.net.cn

在 5.1 中ForwardedHeaderFilter已弃用并被ForwardedHeaderTransformer因此,请求头转发可以在 Exchange 已创建。如果仍然配置了过滤器,则会将其从 filters 和ForwardedHeaderTransformer

安全注意事项

转发的 Headers 存在安全注意事项,因为应用程序无法知道 标头是由代理按预期添加的,还是由恶意客户端添加的。这就是为什么 应将信任边界的代理配置为删除传入的不受信任的转发流量 从外面。您还可以配置ForwardedHeaderTransformerremoveOnly=true,在这种情况下,它会删除但不使用标头。spring-doc.cadn.net.cn

过滤器

WebHandler应用程序接口,您可以使用WebFilter应用 interception 样式 过滤器其余处理链和目标之前的和之后的逻辑WebHandler.使用 WebFlux Config 时,注册一个WebFilter就是这么简单 将其声明为 Spring Bean 并(可选地)通过使用@Order上 bean 声明或通过实现Ordered.spring-doc.cadn.net.cn

CORS

Spring WebFlux 通过对 CORS 配置的注释提供细粒度的支持 控制器。但是,当您将其与 Spring Security 一起使用时,我们建议依赖内置的CorsFilter,它必须在 Spring Security 的过滤器链之前订购。spring-doc.cadn.net.cn

请参阅 CORS 部分和CORSWebFilter了解更多详情。spring-doc.cadn.net.cn

异常

WebHandler应用程序接口,您可以使用WebExceptionHandler处理 异常WebFilterinstances 和目标WebHandler.使用 WebFlux Config 时,注册一个WebExceptionHandler就像将其声明为 Spring Bean 和(可选)通过使用@Order在 Bean 声明上或 通过实施Ordered.spring-doc.cadn.net.cn

下表描述了可用的WebExceptionHandler实现:spring-doc.cadn.net.cn

异常处理程序 描述

ResponseStatusExceptionHandlerspring-doc.cadn.net.cn

提供对ResponseStatusException通过将响应设置为异常的 HTTP 状态代码。spring-doc.cadn.net.cn

WebFluxResponseStatusExceptionHandlerspring-doc.cadn.net.cn

扩展ResponseStatusExceptionHandler,也可以确定 HTTP 状态 的代码@ResponseStatus注释。spring-doc.cadn.net.cn

此处理程序在 WebFlux Config 中声明。spring-doc.cadn.net.cn

Codec

spring-webspring-coremodules 支持序列化和 通过非阻塞 I/O 将字节内容反序列化到更高级别的对象或从更高级别的对象反序列化 反应流背压。下面介绍了此支持:spring-doc.cadn.net.cn

spring-coremodule 提供byte[],ByteBuffer,DataBuffer,ResourceString编码器和解码器实现。这spring-web模块提供 Jackson JSON、Jackson Smile、JAXB2、Protocol Buffers 和其他编码器和解码器以及 用于表单数据、多部分内容、 server-sent 事件等。spring-doc.cadn.net.cn

ClientCodecConfigurerServerCodecConfigurer通常用于配置和 自定义要在应用程序中使用的编解码器。请参阅 配置 HTTP 消息编解码器 部分。spring-doc.cadn.net.cn

Jackson JSON

JSON 和二进制 JSON (Smile) 是 当存在 Jackson 库时,两者都受支持。spring-doc.cadn.net.cn

Jackson2Decoder工作原理如下:spring-doc.cadn.net.cn

  • Jackson 的异步、非阻塞解析器用于聚合字节块流 到TokenBuffer的 JSON 对象。spring-doc.cadn.net.cn

  • TokenBuffer传递给 Jackson'sObjectMapper以创建更高级别的对象。spring-doc.cadn.net.cn

  • 当解码为单值发布者(例如Mono),则有一个TokenBuffer.spring-doc.cadn.net.cn

  • 当解码为多值发布者(例如Flux)、每个TokenBuffer传递给 这ObjectMapper一旦收到足够多的字节用于完全形成的对象。这 input 内容可以是 JSON 数组,也可以是任何以行分隔的 JSON 格式,例如 NDJSON, JSON 行或 JSON 文本序列。spring-doc.cadn.net.cn

Jackson2Encoder工作原理如下:spring-doc.cadn.net.cn

  • 对于单值发布者(例如Mono),只需通过ObjectMapper.spring-doc.cadn.net.cn

  • 对于具有application/json,默认情况下,使用Flux#collectToList()然后序列化生成的集合。spring-doc.cadn.net.cn

  • 对于具有流媒体类型(如application/x-ndjsonapplication/stream+x-jackson-smile、encode、write 和 使用以行分隔的 JSON 格式单独刷新每个值。其他 流媒体类型可以注册到编码器。spring-doc.cadn.net.cn

  • 对于 SSE ,Jackson2Encoder按事件调用,并刷新输出以确保 毫不拖延地交货。spring-doc.cadn.net.cn

默认情况下,两者都Jackson2EncoderJackson2Decoder不支持String.相反,默认假设是一个字符串或一系列字符串 表示序列化的 JSON 内容,由CharSequenceEncoder.如果 您需要从Flux<String>Flux#collectToList()和 对Mono<List<String>>.spring-doc.cadn.net.cn

表单数据

FormHttpMessageReaderFormHttpMessageWriter支持解码和编码application/x-www-form-urlencoded内容。spring-doc.cadn.net.cn

在经常需要从多个位置访问表单内容的服务器端,ServerWebExchange提供专用的getFormData()解析内容的方法 通过FormHttpMessageReader然后缓存结果以供重复访问。 请参阅 表单数据 中的WebHandler应用程序接口部分。spring-doc.cadn.net.cn

一次getFormData()时,无法再从 请求正文。因此,应用程序应通过ServerWebExchange始终如一地访问缓存的表单数据,而不是从原始请求正文中读取。spring-doc.cadn.net.cn

多部分

MultipartHttpMessageReaderMultipartHttpMessageWriter支持解码和 对“multipart/form-data”、“multipart/mixed”和“multipart/related”内容进行编码。 挨次MultipartHttpMessageReader委托人到另一个HttpMessageReader对于实际解析为Flux<Part>然后简单地将部分收集到MultiValueMap. 默认情况下,DefaultPartHttpMessageReader,但这可以通过ServerCodecConfigurer. 有关DefaultPartHttpMessageReader,请参阅javadoc 的DefaultPartHttpMessageReader.spring-doc.cadn.net.cn

在服务器端,可能需要从多个访问多部分表单内容 地方ServerWebExchange提供专用的getMultipartData()解析 内容通过MultipartHttpMessageReader然后缓存结果以供重复访问。 请参阅 Multipart Data 中的WebHandler应用程序接口部分。spring-doc.cadn.net.cn

一次getMultipartData()时,无法再从 请求正文。因此,应用程序必须始终如一地使用getMultipartData()对部分进行重复的、类似 Map 的访问,或者依赖SynchronossPartHttpMessageReader一次性访问Flux<Part>.spring-doc.cadn.net.cn

限制

DecoderHttpMessageReader缓冲部分或全部 input 的实现 stream 可以配置对内存中缓冲的最大字节数的限制。 在某些情况下,之所以发生缓冲,是因为输入被聚合并表示为单个 object — 例如,具有@RequestBody byte[],x-www-form-urlencodeddata 等。流式处理也可能发生缓冲,当 拆分输入流 — 例如,分隔文本、JSON 对象流,以及 等等。对于这些流式处理情况,限制适用于关联的字节数 在流中有一个对象。spring-doc.cadn.net.cn

要配置缓冲区大小,您可以检查给定的DecoderHttpMessageReader暴露一个maxInMemorySizeproperty 属性,如果是这样,Javadoc 将包含有关 default 的详细信息 值。在服务器端,ServerCodecConfigurer提供从 设置所有编解码器,请参阅 HTTP 消息编解码器。在客户端,对 所有编解码器都可以在 WebClient.Builder 中更改。spring-doc.cadn.net.cn

对于 Multipart 解析maxInMemorySize属性限制 非文件部分的大小。对于文件部分,它确定部分达到的阈值 已写入磁盘。对于写入磁盘的文件部分,还有一个额外的maxDiskUsagePerPart属性来限制每个部分的磁盘空间量。还有 一个maxParts属性来限制 Multipart 请求中的段总数。 要在 WebFlux 中配置所有这三个实例,您需要提供一个预配置的MultipartHttpMessageReaderServerCodecConfigurer.spring-doc.cadn.net.cn

当流式传输到 HTTP 响应(例如text/event-stream,application/x-ndjson),请务必定期发送数据,以便 尽早可靠地检测断开连接的客户端。这样的发送可以是 仅注释、空 SSE 事件或任何其他“无作”数据,这些数据实际上可以用作 心跳。spring-doc.cadn.net.cn

DataBuffer

DataBuffer是 WebFlux 中字节缓冲区的表示形式。Spring Core 的 此参考在 Data Buffers and Codecs 一节中提供了更多相关信息。要理解的关键点是,在某些 像 Netty 这样的服务器,字节缓冲区是池化的和引用计数的,并且必须释放 当使用以避免内存泄漏时。spring-doc.cadn.net.cn

WebFlux 应用程序通常不需要关心此类问题,除非它们 直接使用或生成数据缓冲区,而不是依赖编解码器转换为 以及更高级别的对象,或者除非他们选择创建自定义编解码器。对于这样的 情况请查看 Data Buffers 和 Codecs、 尤其是 使用 DataBuffer 的部分。spring-doc.cadn.net.cn

Logging

DEBUGSpring WebFlux 中的级别日志记录被设计为紧凑、最小和 人性化。它侧重于有用的高价值信息 over again 与仅在调试特定问题时有用的其他 cookie 进行比较。spring-doc.cadn.net.cn

TRACE级别日志记录通常遵循与DEBUG(例如,还有 不应是 Firehose),但可用于调试任何问题。此外,一些日志 消息可能会在TRACEDEBUG.spring-doc.cadn.net.cn

良好的日志记录来自使用日志的经验。如果您发现任何 未达到既定目标,请告诉我们。spring-doc.cadn.net.cn

日志 ID

在 WebFlux 中,单个请求可以在多个线程上运行,线程 ID 对于关联属于特定请求的日志消息没有用。这就是为什么 默认情况下,WebFlux 日志消息以特定于请求的 ID 为前缀。spring-doc.cadn.net.cn

在服务器端,日志 ID 存储在ServerWebExchange属性 (LOG_ID_ATTRIBUTE), 而基于该 ID 的完全格式化前缀可从ServerWebExchange#getLogPrefix().在WebClient端,日志 ID 存储在ClientRequest属性 (LOG_ID_ATTRIBUTE) ,而完全格式化的前缀可从ClientRequest#logPrefix().spring-doc.cadn.net.cn

敏感数据

DEBUGTRACE日志记录可以记录敏感信息。这就是为什么表单参数和 默认情况下,标头是屏蔽的,您必须显式启用其日志记录。spring-doc.cadn.net.cn

以下示例显示了如何对服务器端请求执行此作:spring-doc.cadn.net.cn

@Configuration
@EnableWebFlux
class MyConfig implements WebFluxConfigurer {

	@Override
	public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
		configurer.defaultCodecs().enableLoggingRequestDetails(true);
	}
}
@Configuration
@EnableWebFlux
class MyConfig : WebFluxConfigurer {

	override fun configureHttpMessageCodecs(configurer: ServerCodecConfigurer) {
		configurer.defaultCodecs().enableLoggingRequestDetails(true)
	}
}

以下示例说明如何对客户端请求执行此作:spring-doc.cadn.net.cn

Consumer<ClientCodecConfigurer> consumer = configurer ->
		configurer.defaultCodecs().enableLoggingRequestDetails(true);

WebClient webClient = WebClient.builder()
		.exchangeStrategies(strategies -> strategies.codecs(consumer))
		.build();
val consumer: (ClientCodecConfigurer) -> Unit  = { configurer -> configurer.defaultCodecs().enableLoggingRequestDetails(true) }

val webClient = WebClient.builder()
		.exchangeStrategies({ strategies -> strategies.codecs(consumer) })
		.build()

附加程序

日志记录库(如 SLF4J 和 Log4J 2)提供了异步记录器,可避免 阻塞。虽然这些有其自身的缺点,例如可能会丢弃消息 无法排队进行日志记录,它们是目前最好的可用选项 用于反应式、非阻塞应用程序。spring-doc.cadn.net.cn

自定义编解码器

应用程序可以注册自定义编解码器以支持其他媒体类型、 或默认编解码器不支持的特定行为。spring-doc.cadn.net.cn

开发人员表示的某些配置选项在默认编解码器上强制执行。 自定义编解码器可能希望有机会与这些首选项保持一致, 例如强制实施缓冲限制记录敏感数据spring-doc.cadn.net.cn

以下示例说明如何对客户端请求执行此作:spring-doc.cadn.net.cn

WebClient webClient = WebClient.builder()
		.codecs(configurer -> {
				CustomDecoder decoder = new CustomDecoder();
                   configurer.customCodecs().registerWithDefaultConfig(decoder);
		})
		.build();
val webClient = WebClient.builder()
		.codecs({ configurer ->
				val decoder = CustomDecoder()
           		configurer.customCodecs().registerWithDefaultConfig(decoder)
		 })
		.build()