DoubleReceive for request body

预计阅读时间:2分钟

DoubleReceive功能提供了多次调用ApplicationCall.receive的功能,而没有RequestAlreadyConsumedException异常. 当某个功能正在使用请求主体,因此处理程序无法再次接收它时,这通常是有意义的.

此功能是实验性的,包括所有选项和行为. 不能保证在将来的版本中以相同的方式工作.

目录:

Usage

DoubleReceive功能安装到ApplicationCall中

install(DoubleReceive)

之后,您可以多次收到呼叫,并且每次调用都可能返回相同的实例.

val first = call.receiveText()
val theSame = call.receiveText()

并非所有内容都能收到两次. 例如,除非启用了receiveEntireContent选项,否则无法两次接收流或频道.

始终可以使用此功能两次接收的类型为: ByteArrayStringParameters以及ContentNegotiation功能提供的所有类型(例如,从JSON有效负载反序列化的对象).

如果不能在没有receiveEntireContent情况下从同一呼叫接收不同类型的数据,则不能保证它可以工作,但是在某些特定情况下可能会起作用. 例如,在接收字节数组之后接收文本始终有效.

启用receiveEntireContent ,接收不同类型的数据将始终有效. 频道或流的双重接收也可以工作. 但是, receive从一开始就执行了整个接收管道,因此每次执行所有内容转换和转换器的时间可能比禁用该选项时要慢.

Comparison:

receiveEntireContent 相同类型 不同类型 channel
enabled re-run 是的,重新运行 yes
disabled 缓存同一个实例 一般没有 no

Custom types

如果安装了自定义内容转换(例如,通过拦截接收管道),则默认情况下,如果没有receiveEntireContent选项,则无法重新接收转换后的值. 但是,可以通过指定reusableValue选项将转换后的值对象标记为可reusableValue

val converted = .... // convert somehow from a request payload
proceedWith(ApplicationReceiveRequest(receive.typeInfo, converted, reusableValue = true))

Options

  • receiveEntireContent启用后,对于每个请求,整个内容将被接收并存储为字节数组. 当需要接收完全不同的类型时,这很有用. 您还可以接收流和频道. 请注意,启用此功能会使整个接收管道针对每个其他接收管道执行.

by  ICOPY.SITE