Spring Webflux and Observable responses not working

走远了吗. 提交于 2019-12-12 18:17:33

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!