当我在响应正文中返回值时,Spring WebFlux抛出“生产者”类型是未知的

时间:2019-10-23 08:54:07

标签: spring-boot kotlin spring-webflux reactive

我正在将Spring Boot与Kotlin一起使用,现在尝试通过传递反应式服务的处理程序来从GET Restful服务获取状态值。

我可以看到我传递的处理程序位于请求中,但是每当构建主体时,都会出现此异常:

java.lang.IllegalArgumentException: 'producer' type is unknown to ReactiveAdapterRegistry
    at org.springframework.util.Assert.notNull(Assert.java:198) ~[spring-core-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException

这是我的代码

@Bean
    fun getReceiptConversionStatus() = router {
        accept(MediaType.APPLICATION_JSON).nest {
            GET("/BsGetStatus/{handler}", ::handleGetStatusRequest)
        }
    }
    private fun handleGetStatusRequest(serverRequest: ServerRequest): Mono<ServerResponse> = ServerResponse
            .ok()
            .contentType(MediaType.APPLICATION_JSON)
            .body(GetStatusViewmodel(fromObject(serverRequest.pathVariable("handler"))), GetStatusViewmodel::class.java)
            .switchIfEmpty(ServerResponse.notFound().build())

那是我的Viewmodel:

data class GetStatusViewmodel(
        @JsonProperty("handler") val documentHandler: String
)

4 个答案:

答案 0 :(得分:8)

对我来说,我正在做这样的事情:

webClient.post()
    .uri("/some/endpoint")
    .body(postRequestObj, PostRequest.class) // erroneous line 
    .accept(MediaType.APPLICATION_JSON)
    .retrieve()
    .bodyToMono(PostResponse.class)
    .timeout(Duration.ofMillis(5000))

当查看该功能body()的springs文档时,将对此进行解释:

Variant of body(Publisher, Class) that allows using any producer that can be resolved to Publisher via ReactiveAdapterRegistry.

Parameters:
     producer - the producer to write to the request
     elementClass - the type of elements produced

Returns:
    this builder

因此第一个参数不能只是任何对象,它必须是生产者。更改上面的代码以将对象包装在Mono中可以为我解决此问题。

webClient.post()
    .uri("/some/endpoint")
    .body(Mono.just(postRequestObj), PostRequest.class)
    .accept(MediaType.APPLICATION_JSON)
    .retrieve()
    .bodyToMono(PostResponse.class)
    .timeout(Duration.ofMillis(5000))

参考:https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/reactive/function/client/WebClient.RequestBodySpec.html

答案 1 :(得分:0)

FluxMonoProducers。他们生产东西。您没有在正文中传递producer,这就是您得到错误的原因,它无法识别所传递的生产者,因为您正在传递GetStatusViewmodel

您的身体必须为Mono<GetStatusViewmodel>类型。您可以将body替换为syncBody(它将自动为您包装),也可以在通过之前使用GetStatusViewodelMono包裹在Mono#just中进入body函数。

答案 2 :(得分:0)

我实际上已经解决了它,我将其张贴在这里,以防万一有人会犯与我相同的错误:(对于使用Java的人来说,这是一个典型的错误,导入错误 >。

我在应用程序“我更新了问题以匹配我的实际代码” 中使用了fromObject()方法。您可以在这两个导入中找到此函数,而我正在使用重载的body()函数之一来传递此错误放置的函数:

//this is the wrong import I was using
import org.springframework.web.reactive.function.server.EntityResponse.fromObject
//this is the correct one for building the mono body
import org.springframework.web.reactive.function.BodyInserters.fromObject

通过使用BodyInserters中的方法,您可以将fromObject(T)传递给body方法,它将返回单声道结果​​。

答案 3 :(得分:0)

指定的代码解决了问题

public Mono getName(ServerRequest request) { 返回 ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).bodyValue(生日); }