Reputation: 1559
I'm using Spring Boot with Kotlin, and now trying to get status value from a GET restful service by passing a handler for a reactive service.
I can see that the handler I'm passing is in the request, but whenever I'm building the body, I get this exception:
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
Here is my code:
@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())
and that's my Viewmodel:
data class GetStatusViewmodel(
@JsonProperty("handler") val documentHandler: String
)
Upvotes: 31
Views: 42115
Reputation: 1559
I actually solved it, and I will post it here just in case somebody would make the same mistake I did.
I was using fromObject()
method in my application "I updated the question to match my actual code". You can find this function in both of these imports, and I was using one of the overloaded body()
functions to pass this wrong-placed function:
//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
By using the method from BodyInserters
, you will be able to pass fromObject(T)
to the body method and it will return the mono result.
Upvotes: 4
Reputation: 71
The specified code resolved the issue
public Mono<ServerResponse> getName(ServerRequest request) {
return ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(birthday);
}
Upvotes: 2
Reputation: 1922
For me, I was doing something like this:
webClient.post()
.uri("/some/endpoint")
.body(postRequestObj, PostRequest.class) // erroneous line
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(PostResponse.class)
.timeout(Duration.ofMillis(5000))
When looking at the springs docs for that function body()
, this is what's explained:
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
So the first parameter can't just be any object, it has to be a producer. Changing my above code to wrap my object around in a Mono fixed this issue for me.
webClient.post()
.uri("/some/endpoint")
.body(Mono.just(postRequestObj), PostRequest.class)
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(PostResponse.class)
.timeout(Duration.ofMillis(5000))
Upvotes: 44
Reputation: 14732
Flux
and Mono
s are Producers
. They produce stuff. You are not passing in a producer
in the body thats why you get the error, it doesn't recognize the producer you are passing, because you are passing in a GetStatusViewmodel
.
Your body needs to be of type Mono<GetStatusViewmodel>
. You can either replace body
with bodyValue
(it will automatically wrap it for you) or you can wrap your GetStatusViewodel
in a Mono
using Mono#just
before passing it into the body
function.
Upvotes: 36