问题
I just created a simple Spring Boot application using spring-boot-starter-webflux with version 2.0.0.BUILD-SNAPSHOT which brings spring-webflux version 5.0.0.BUILD-SNAPSHOT and same for Spring Core, Beans, Context, etc.
If I create a simple @RestController
and provide a @GetMapping
that simply returns a Flux<String>
, then everything works as expected.
However, if I change from Flux
to RxJava's Observable
, I get this error:
org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
Debugging a bit through the code I found that Jackson's ObjectMapper
somehow registers Flux
, Mono
and the rest of reactive types in its typeFactory, so later the MappingJackson2HttpMessageConverter
knows how to (de)-serialize them.
However, it's not the case when I use an Observable
: I don't find the type Observable
or Single
registered in the ObjectMapper
's type factory, so I get the aforementioned error.
Has anyone experienced this issue? Am I missing any dependency? Do I need to manually tell Jackson how to (de)-serialize from RxJava constructs? But why does Jackson already know about Flux and Mono?
Thanks for your help.
EDITED:
I'm using RxJava 1.2.7. Here is my pom.xml:
<dependencies>
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
</dependency>
<!-- RxJava dependeencies -->
<dependency>
<groupId>io.reactivex</groupId>
<artifactId>rxjava</artifactId>
<version>1.2.7</version>
</dependency>
</dependencies>
And here is the example of my controller code:
/**
* Get all the available tasks.
*
* @return the list of tasks
*/
@GetMapping(path = "/task")
@ResponseStatus(HttpStatus.OK)
public Observable<TaskView> allTasks(@AuthenticationPrincipal LoggedUserVO principal) {
return this.pocComponent.getAllTasks()
.map(t -> ViewConverter.convertFromTaskDocument(t, principal));
}
回答1:
You are probably missing the following dependency to make it works:
<dependency>
<groupId>io.reactivex</groupId>
<artifactId>rxjava-reactive-streams</artifactId>
<version>1.2.1</version>
</dependency>
Changes in various RxJava 1.x versions made it challenging for us to support it out of the box, that's why we prefer to rely on the official RxJava -> Reactive Streams adapter. Notice that RxJava 2.x is supported without requiring additional dependencies (it is natively built on top of Reactive Streams).
I am going to update Spring WebFlux reference documentation to specify this is required to have RxJava 1.x support.
回答2:
So, Flux
and Mono
are Spring names, as Spring has the Not-Invented-Here syndrome.
You can either register a handler that does the conversion to types that Spring knows about, use the AsyncResponse facility that Jersey provides, or add toBlocking everywhere.
来源:https://stackoverflow.com/questions/42748775/spring-webflux-and-observable-responses-not-working