当前位置: 首页 > 知识库问答 >
问题:

在Kotlin中处理Spring WebFlux WebClient超时

姚宪
2023-03-14

我正在Kotlin(1.4.30)中使用Spring WebFlux WebClient(引导2.4.3)执行一个get http调用。当请求超时时,它以异常方式失败,但我希望返回一个默认值。我看到对onerroronstatus等的引用在retrieve()之后使用,但在我的示例中似乎没有这些引用(只有bodytoentityawaitexchange)

电话:

suspend fun conversation(id: String): Conversation =
    client.get().uri("/conversation/{id}", id).retrieve().awaitBody()

连接和读取超时的WebClient配置:

fun webClient(url: String, connectTimeout: Int, readTimeout: Long, objectMapper: ObjectMapper): WebClient =
    WebClient.builder()
      .baseUrl(url)
      .exchangeStrategies(
        ExchangeStrategies.builder()
          .codecs { configurer -> configurer.defaultCodecs().jackson2JsonDecoder(Jackson2JsonDecoder(objectMapper)) }
          .build())
      .clientConnector(
        ReactorClientHttpConnector(
          HttpClient.create()
            .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectTimeout)
            .doOnConnected { connection ->
              connection.addHandlerLast(ReadTimeoutHandler(readTimeout, TimeUnit.MILLISECONDS))
            }))
      .build()

响应模型:

kotlin prettyprint-override">@JsonIgnoreProperties(ignoreUnknown = true)
data class Conversation(
  val replyTimestamp: Map<String, String>,
)
  private val defaultConversation = Conversation(emptyMap())

  suspend fun conversation(id: String): Conversation =
    client.get()
      .uri("/conversation/{id}", id)
      .awaitExchange {
          response -> if (response.statusCode() == HttpStatus.OK)  response.awaitBody() else defaultConversation
      }

回应:

{
  "replyTimestamp": {
    "1": "2021-02-23T15:30:28.753Z",
    "2": "2021-02-23T16:30:28.753Z"
  }
}

它的模拟配置:

{
  "mappings":
  [
    {
      "priority": 1,
      "request": {
        "method": "GET",
        "urlPathPattern": "/conversation/1"
      },
      "response": {
        "status": 200,
        "fixedDelayMilliseconds": 1010,
        "headers": {
          "content-type": "application/json;charset=utf-8"
        },
        "bodyFileName": "conversation1.json"
      }
    }
  ]
}

共有1个答案

太叔俊侠
2023-03-14

之所以出现异常,是因为在您的方法中,您希望得到一个类型为Conversation的响应,但由于您接收到一个错误,所以正文不同。在本例中,处理响应的方式应该是首先查看HTTP状态代码,然后相应地转换正文。下面是Spring.io https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html中的一个示例

在您的情况下,当您收到错误的状态代码时,您应该创建一个新的空对话并返回它

val entity = client.get()
  .uri("/conversation/{id}", id)
  .accept(MediaType.APPLICATION_JSON)
  .awaitExchange {
        if (response.statusCode() == HttpStatus.OK) {
             return response.awaitBody<Conversation>()
        }
        else if (response.statusCode().is4xxClientError) {
             return response.awaitBody<ErrorContainer>()
        }
        else {
             throw response.createExceptionAndAwait()
        }
  }
 类似资料:
  • 我的处理器中有一个简单的注释,如下所示: 这适用于java文件,但一旦我将文件转换为kotlin,注释的导入就不再有效。为什么? 我需要改变什么才能让他的注释也在Kotlin中工作?从文档中,我可以看到kotlin与java注释100%兼容,所以我有点困惑这里有什么问题...如果处理器不工作,需要调整以与kotlin一起工作,我会理解,但我不知道为什么导入本身不工作... 我说的图书馆在这里:ht

  • 问题内容: 我试图用一个批量一些 KTable 值,并送他们。似乎30秒钟超出了使用者超时间隔,在此间隔之后,Kafka认为该使用者已失效并释放了分区。 我尝试提高 轮询 和 提交间隔 的频率来避免这种情况: 不幸的是,这些错误仍在发生: (很多) 其次是: 显然,我需要更频繁地将心跳发送回服务器。怎么样? 我的拓扑是: 该 KTable 是关键,每30秒分组值。在 Processor.init(

  • 前言 sender的run 调用done方法,并传入TimeoutException

  • 我目前正在尝试用Kotlin为Android编写一个注释处理器。项目结构如下: 项目/构建.gradle 注释/build.gradle 样品/build.gradle Annotation.kt AnnotationProcessor.kt 使用kapt,构建在示例javaPreCompileDebug上中断,并显示以下消息: 当我用注释处理器替换 kapt 时,构建在示例:转换类上中断了以下消

  • Spring docs表示,需要手动为WebClient配置http客户机以设置超时:https://docs.Spring.io/Spring/docs/current/spring-framework-reference/web-reactive.html#webflux-client-builder-reactor-timeout。但是,由于WebClient返回反应单声道,所以可以(在AP

  • 问题内容: 我正在urllib2的urlopen中使用timeout参数。 我如何告诉Python,如果超时到期,应该引发自定义错误? 有任何想法吗? 问题答案: 在极少数情况下要使用。这样做会捕获可能很难调试的 任何 异常,并且会捕获包括和在内的异常,这些异常会使您的程序恼人。 最简单的说,您会发现: 以下内容应捕获连接超时时引发的特定错误: