文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Spring WebFlux核心组件详解

2024-12-13 14:53

关注

概述

spring-web模块包含了对响应式web应用程序的以下基本支持:

  1. HttpHandler:处理HTTP请求的基本协议,包括非阻塞I/O和响应式流背压,以及Reactor Netty、Undertow、Tomcat、Jetty和任何Servlet 3.1+容器的适配器。
  2. WebHandler API:稍微高级一点的,用于处理请求的通用web API,在此基础上构建具体的编程模型,如带注释的控制器和函数式端点。

HttpHandler

HttpHandler是一个简单的协议,只有一个方法来处理请求和响应。它故意最小化,其主要和唯一的目的是在不同的HTTP服务器api上提供最小的抽象。

支持的服务器api如下表所示:

服务器

服务的API

反应式流支持

Netty

Netty API

Reactor Netty

Undertow

Undertow API

spring-web: Undertow到Reactive Streams桥接

Tomcat

Servlet 3.1 non-blocking I/O; Tomcat API to read and write ByteBuffers vs byte[]

spring-web:Servlet 3.1非阻塞 I/O到Reactive Streams桥接

Jetty

Servlet 3.1 non-blocking I/O; Jetty API to write ByteBuffers vs byte[]

spring-web:Servlet 3.1非阻塞 I/O到Reactive Streams桥接

Servlet 3.1 container

Servlet 3.1 non-blocking I/O

spring-web: Servlet 3.1非阻塞 I/O到Reactive Streams桥接

下表描述了服务器依赖关系:

服务器

Group id

Artifact name

Reactor Netty

io.projectreactor.netty

reactor-netty

Undertow

io.undertow

undertow-core

Tomcat

org.apache.tomcat.embed

tomcat-embed-core

Jetty

org.eclipse.jetty

jetty-server, jetty-servlet

下面的代码片段显示了在每个服务器API中使用HttpHandler适配器:

HttpHandler handler = WebHttpHandlerBuilder.applicationContext(this.applicationContext).build();
ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(handler);
HttpServer.create().host(host).port(port).handle(adapter).bind().block();
HttpHandler handler = WebHttpHandlerBuilder.applicationContext(this.applicationContext).build();
UndertowHttpHandlerAdapter adapter = new UndertowHttpHandlerAdapter(handler);
Undertow server = Undertow.builder().addHttpListener(port, host).setHandler(adapter).build();
server.start();
HttpHandler handler = WebHttpHandlerBuilder.applicationContext(this.applicationContext).build();
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();
HttpHandler handler = WebHttpHandlerBuilder.applicationContext(this.applicationContext).build();
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();

要将war部署到任何Servlet 3.1+容器,你可以扩展并在war中包含
AbstractReactiveWebInitializer。这个类用ServletHttpHandlerAdapter封装了一个HttpHandler,并将其注册为Servlet。

部分源码:​

public abstract class AbstractReactiveWebInitializer implements WebApplicationInitializer {
public void onStartup(ServletContext servletContext) throws ServletException {
String servletName = getServletName();
ApplicationContext applicationContext = createApplicationContext();
refreshApplicationContext(applicationContext);
registerCloseListener(servletContext, applicationContext);


// 与上面的服务器一样通过WebHttpHandlerBuilder构建HttpHandler对象
HttpHandler httpHandler = WebHttpHandlerBuilder.applicationContext(applicationContext).build();
// 该类实现了javax.servlet.Servlet接口
ServletHttpHandlerAdapter servlet = new ServletHttpHandlerAdapter(httpHandler);


ServletRegistration.Dynamic registration = servletContext.addServlet(servletName, servlet);
registration.setLoadOnStartup(1);
registration.addMapping(getServletMapping());
registration.setAsyncSupported(true);
}
}

WebHandler

org.springframework.web.server包构建在HttpHandler契约之上,为通过多个WebExceptionHandler、多个WebFilter和单个WebHandler组件的链处理请求提供通用的web API。只需指向自动检测组件的Spring ApplicationContext,或者向构建器注册组件,就可以将该链与WebHttpHandlerBuilder组合在一起。

HttpHandler的目标很简单,就是抽象出不同的HTTP服务器,而WebHandler API的目标是提供web应用中常用的更广泛的功能,例如:

特殊bean类型

下表列出了WebHttpHandlerBuilder可以在Spring ApplicationContext中自动检测或直接注册的组件:

Bean name

Bean type

Count

Description

WebExceptionHandler

0..N

为来自WebFilter实例链和目标WebHandler的异常提供处理。

WebFilter

0..N

在过滤器链的其余部分和目标WebHandler的前后应用拦截样式逻辑。

webHandler

WebHandler

1

请求处理程序。

webSessionManager

WebSessionManager

0..1

通过ServerWebExchange上的方法公开的WebSession实例管理器。默认为DefaultWebSessionManager。

serverCodecConfigurer

ServerCodecConfigurer

0..1

用于访问HttpMessageReader实例,解析表单数据和multipart数据,然后通过ServerWebExchange上的方法公开这些数据。默认情况下是servercodecconfiguration.create()。

localeContextResolver

LocaleContextResolver

0..1

LocaleContext的解析器通过ServerWebExchange上的方法公开。默认为AcceptHeaderLocaleContextResolver。

forwardedHeaderTransformer

ForwardedHeaderTransformer

0..1

对于处理转发的类型头,可以提取并删除它们,也可以只删除它们。默认不使用。

Form Data

ServerWebExchange公开了以下访问表单数据的方法:

Mono<MultiValueMap<String, String>> getFormData();

DefaultServerWebExchange使用配置的HttpMessageReader将表单数据(
application/x-www-form-urlencoded)解析为MultiValueMap。默认情况下,FormHttpMessageReader被配置为由ServerCodecConfigurer bean使用。

Multipart Data

ServerWebExchange公开了以下访问多部分数据的方法:

Mono<MultiValueMap<String, Part>> getMultipartData();

DefaultServerWebExchange使用配置的HttpMessageReader>来将multipart/form-data内容解析为MultiValueMap。默认情况下,这是DefaultPartHttpMessageReader,它没有任何第三方依赖。另外,还可以使用基于Synchronoss nio Multipart库的SynchronossPartHttpMessageReader。两者都是通过ServerCodecConfigurer bean进行配置的。

要以流式方式解析多部分数据,你可以使用HttpMessageReader返回的` Flux `。例如,在带注释的控制器中,使用@RequestPart意味着通过名称访问各个部分,就像map一样,因此需要完整解析多个部分的数据。相比之下,可以使用@RequestBody将内容解码到Flux,而无需收集到MultiValueMap。

Filters

在WebHandler API中,你可以使用WebFilter在过滤器和目标WebHandler处理链的其余部分之前和之后应用拦截风格的逻辑。当使用WebFlux配置时,注册WebFilter就像把它声明为Spring bean一样简单,并且(可选地)通过在bean声明上使用@Order或实现Ordered来表示优先级。

Exceptions

在WebHandler API中,可以使用WebExceptionHandler来处理来自WebFilter实例链和目标WebHandler的异常。当使用WebFlux配置时,注册WebExceptionHandler就像声明它为Spring bean一样简单,并且(可选)通过在bean声明上使用@Order或实现Ordered来表示优先级。

下表描述了可用的WebExceptionHandler实现:

Exception Handler

Description

ResponseStatusExceptionHandler

通过将响应设置为异常的HTTP状态码,提供对ResponseStatusException类型异常的处理。

WebFluxResponseStatusExceptionHandler

扩展了ResponseStatusExceptionHandler,它还可以确定任何异常的@ResponseStatus注解的HTTP状态码。

这个处理程序是在WebFlux配置中声明的。

Codecs

spring-web和spring-core模块通过非阻塞I/O提供响应式流回压,支持序列化和反序列化与高层对象之间的字节内容。下面介绍这种支持:

spring-core模块提供了byte[]、ByteBuffer、DataBuffer、Resource和String编码器和解码器的实现。spring-web模块提供了Jackson JSON、Jackson Smile、JAXB2、Protocol buffer和其他Encoder和Decoder,以及针对表单数据、多部分内容、服务器发送事件等只支持web的HTTP消息阅读器和writer实现。

来源:实战案例锦集内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯