b spring mvc 之 Endpoints 服务端配置 & 异步请求
1.4 function Endpoints
轻量的Spring mvc,类似requestmapping。
1.5 URI Links
Work with URI Links
后期再了解。
1.6 异步请求
MVC集成和扩展了Servlet 3.0的异步请求处理
-
controller方法返回
DeferredResult
和Callable
提供单个方法的异步支持。 -
Controllers can stream multiple values, including
SSE
andraw data
. -
Controllers can
use reactive clients
andreturn reactive types
for response handling.
1.6.1 DeferredResult
异步请求开启后,任何返回值可以被封装成DeferredResult
1.6.2 Callable
java.util.concurrent.Callable
1.6.3 Processing
异步请求流的处理流程
- ServletRequest被放到异步模型中,通过使用
request.startAsync()
。这样的好处是Servlet可以退出但是reponse后续在进程完成后返回 - 调用
request.startAsync()
返回AsyncContext
。可以用这个Context做一些对异步处理的控制。比图提供dispatch
方法。 -
ServletRequest
提供对当前的DispatcherType
的获取方式,你可以用来初始化请求。
DeferredResult
- controller 返回DeferredResult,并把它保存在内存里或者可以拿到的地方。
- Spring MVC calls request.startAsync()
- 同时 DispatcherServlet 和所有的配置的filters退出,但是response保留打开。
- 应用设置
DeferredResult
,然后MVC把request 返回分发到Servlet container。 -
DispatcherServlet
再次被调用处理异步返回的结果。
Callable processing works as follows
- controller返回
Callable
- MVC 调用
request.startAsync()
和提交Callable
到TaskExecutor
。 - 同时Servlet container thread中存在的
DispatcherServlet
和filters退出线程。 - 最终Callable被执行,mvc把结果写到Servlet容器
-
DispatcherServlet
再次被调用
Exception Handling
异常的处理
When you use a DeferredResult
, you can choose whether to call setResult
or setErrorResult
。
异常处理和前面没什么区别。
Interception
HandlerInterceptor实例的类型可以为AsyncHandlerInterceptor,以在启动异步处理的初始请求(而不是postHandle和afterCompletion)上接收afterConcurrentHandlingStarted回调。
HandlerInterceptor实现也可以注册CallableProcessingInterceptor或DeferredResultProcessingInterceptor,以与异步请求的生命周期更深入地集成(例如,处理超时事件)。 有关更多详细信息,请参见AsyncHandlerInterceptor。
DeferredResult提供onTimeout(Runnable)和onCompletion(Runnable)回调。 有关更多详细信息,请参见DeferredResult的javadoc。 可以用Callable代替WebAsyncTask,它公开了超时和完成回调的其他方法。
1.6.4 HTTP Streaming
使用DeferredResult
和 Callable
来做single 异常返回,但是如果有多个呢。
Objects
ResponseBodyEmitter
产生一个对象流,被
你可以用ResponseBodyEmitter
作为ResponseEntity的body。
当emitter
发生IO异常时,应用不会调用emitter.complete or emitter.completeWithError。而是AsyncListener
会检测到。Spring MVC 去做completeWithError
。
SSE
SseEmitter
是ResponseBodyEmitter的自理,提供对Server-Sent Events
的支持,符合W3C SSE规范。
Raw Data
有时直接使用OutputStream
很方便,比如文件下载。你可以使用StreamingResponseBody
。
1.6.5 Reactive Types
反应器类型。
1.6.6 Disconnects
断开连接。无论使用SseEmitter
还是reactive types
,当Streaming周期性的发送数据时,都面临client 断开连接。send端会拿到空的SSE事件等,或者做心跳连接等。
这时可以考虑使用STOMP over WebSocket
等解决方案,他们内置了心跳连接机制。
1.6.7 配置
Servlet Container的配置
Filter和 ServletasyncSupported
设置为true
去打开。额外,filter mapping打开ASYNC javax.servlet.DispatchType
。
java配置AbstractAnnotationConfigDispatcherServletInitializer
去处理。
等同于用web.xml配置添加
true
ASYNC