Spring Reactive xml有效内容异常java.lang.IllegalStateException:无法解析类型为' reactor.core.publisher.Mono'的参数0

时间:2017-02-28 15:50:15

标签: spring spring-webflux

我有一个春季启动应用程序。尝试通过postman将xml有效负载发送到Post请求。我得到以下例外

java.lang.IllegalStateException: Failed to resolve argument 0 of type 'reactor.core.publisher.Mono' on public reactor.core.publisher.Mono<com.event.gateway.rest.controller.Sir> com.event.gateway.rest.controller.WBController.hello(reactor.core.publisher.Mono<com.event.gateway.rest.controller.Sir>)
    at org.springframework.web.reactive.result.method.InvocableHandlerMethod.getArgumentError(InvocableHandlerMethod.java:198) ~[spring-webflux-5.0.0.BUILD-SNAPSHOT.jar:5.0.0.BUILD-SNAPSHOT]
    at org.springframework.web.reactive.result.method.InvocableHandlerMethod.resolveArg(InvocableHandlerMethod.java:193) ~[spring-webflux-5.0.0.BUILD-SNAPSHOT.jar:5.0.0.BUILD-SNAPSHOT]
    at org.springframework.web.reactive.result.method.InvocableHandlerMethod.lambda$null$1(InvocableHandlerMethod.java:149) ~[spring-webflux-5.0.0.BUILD-SNAPSHOT.jar:5.0.0.BUILD-SNAPSHOT]
    at java.util.Optional.orElseGet(Optional.java:267) ~[na:1.8.0_91]
    at org.springframework.web.reactive.result.method.InvocableHandlerMethod.lambda$resolveArguments$2(InvocableHandlerMethod.java:147) ~[spring-webflux-5.0.0.BUILD-SNAPSHOT.jar:5.0.0.BUILD-SNAPSHOT]
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) ~[na:1.8.0_91]
    at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) ~[na:1.8.0_91]
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) ~[na:1.8.0_91]
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) ~[na:1.8.0_91]
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[na:1.8.0_91]
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:1.8.0_91]
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) ~[na:1.8.0_91]
    at org.springframework.web.reactive.result.method.InvocableHandlerMethod.resolveArguments(InvocableHandlerMethod.java:153) ~[spring-webflux-5.0.0.BUILD-SNAPSHOT.jar:5.0.0.BUILD-SNAPSHOT]
    at org.springframework.web.reactive.result.method.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:117) ~[spring-webflux-5.0.0.BUILD-SNAPSHOT.jar:5.0.0.BUILD-SNAPSHOT]
    at org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter.lambda$handle$3(RequestMappingHandlerAdapter.java:312) ~[spring-webflux-5.0.0.BUILD-SNAPSHOT.jar:5.0.0.BUILD-SNAPSHOT]
    at reactor.core.publisher.MonoThenMap$MonoThenApplyMain.onNext(MonoThenMap.java:100) [reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:928) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.MonoThenIgnore$MonoThenIgnoreMain.drain(MonoThenIgnore.java:145) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.MonoThenIgnore.subscribe(MonoThenIgnore.java:54) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.MonoThenMap.subscribe(MonoThenMap.java:57) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.MonoThenMap$MonoThenApplyMain.onNext(MonoThenMap.java:130) [reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:68) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:78) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.innerNext(FluxConcatMap.java:263) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.FluxConcatMap$ConcatMapInner.onNext(FluxConcatMap.java:743) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:119) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:928) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.MonoThenIgnore$MonoThenAcceptSubscriber.onNext(MonoThenIgnore.java:261) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:1657) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.MonoThenIgnore$MonoThenAcceptSubscriber.onSubscribe(MonoThenIgnore.java:250) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:54) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:59) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.MonoThenIgnore$MonoThenIgnoreMain.drain(MonoThenIgnore.java:151) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.MonoThenIgnore.subscribe(MonoThenIgnore.java:54) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.MonoMapFuseable.subscribe(MonoMapFuseable.java:60) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.drain(FluxConcatMap.java:402) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.onSubscribe(FluxConcatMap.java:203) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:97) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:57) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.FluxConcatMap.subscribe(FluxConcatMap.java:126) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.MonoNext.subscribe(MonoNext.java:41) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.MonoOtherwiseIfEmpty.subscribe(MonoOtherwiseIfEmpty.java:44) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.MonoThenMap.subscribe(MonoThenMap.java:57) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.MonoThenMap.subscribe(MonoThenMap.java:57) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.MonoOtherwise.subscribe(MonoOtherwise.java:44) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.MonoOtherwise.subscribe(MonoOtherwise.java:44) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.MonoOtherwise.subscribe(MonoOtherwise.java:44) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.MonoThenIgnore$MonoThenIgnoreMain.drain(MonoThenIgnore.java:169) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.MonoThenIgnore.subscribe(MonoThenIgnore.java:54) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.MonoOtherwise.subscribe(MonoOtherwise.java:44) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.core.publisher.MonoPeekTerminal.subscribe(MonoPeekTerminal.java:62) ~[reactor-core-3.0.5.RELEASE.jar:3.0.5.RELEASE]
    at reactor.ipc.netty.channel.ChannelOperations.applyHandler(ChannelOperations.java:405) ~[reactor-netty-0.6.1.RELEASE.jar:0.6.1.RELEASE]
    at reactor.ipc.netty.http.server.HttpServerOperations.onHandlerStart(HttpServerOperations.java:353) ~[reactor-netty-0.6.1.RELEASE.jar:0.6.1.RELEASE]
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163) ~[netty-all-4.1.8.Final.jar:4.1.8.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:403) ~[netty-all-4.1.8.Final.jar:4.1.8.Final]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:445) ~[netty-all-4.1.8.Final.jar:4.1.8.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858) ~[netty-all-4.1.8.Final.jar:4.1.8.Final]
    at java.lang.Thread.run(Thread.java:745) ~[na:1.8.0_91]
Caused by: java.lang.UnsupportedOperationException: null
    at org.springframework.core.codec.AbstractDecoder.decodeToMono(AbstractDecoder.java:64) ~[spring-core-5.0.0.BUILD-SNAPSHOT.jar:5.0.0.BUILD-SNAPSHOT]
    at org.springframework.http.codec.DecoderHttpMessageReader.readMono(DecoderHttpMessageReader.java:84) ~[spring-web-5.0.0.BUILD-SNAPSHOT.jar:5.0.0.BUILD-SNAPSHOT]
    at org.springframework.web.reactive.result.method.annotation.AbstractMessageReaderArgumentResolver.readBody(AbstractMessageReaderArgumentResolver.java:160) ~[spring-webflux-5.0.0.BUILD-SNAPSHOT.jar:5.0.0.BUILD-SNAPSHOT]
    at org.springframework.web.reactive.result.method.annotation.RequestBodyArgumentResolver.resolveArgument(RequestBodyArgumentResolver.java:78) ~[spring-webflux-5.0.0.BUILD-SNAPSHOT.jar:5.0.0.BUILD-SNAPSHOT]
    at org.springframework.web.reactive.result.method.InvocableHandlerMethod.resolveArg(InvocableHandlerMethod.java:184) ~[spring-webflux-5.0.0.BUILD-SNAPSHOT.jar:5.0.0.BUILD-SNAPSHOT]
    ... 56 common frames omitted

以下是POM

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.event.gateway</groupId>
    <artifactId>endpoint-rest</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>vu-ms-event-gateway</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.BUILD-SNAPSHOT</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>


</project>

控制器

package com.event.gateway.rest.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;



@Controller
public class WBController {

    @RequestMapping(value ="hello", consumes ="application/xml", produces="application/xml", method=RequestMethod.POST)
    @ResponseBody
    public Mono <Sir> hello(@RequestBody Mono<Sir> requestBody) {
        Flux<String> mono =  Mono.just("")
                .concatWith(Mono.from(requestBody)
                        .flatMap(sir -> Flux.fromArray(sir.getLastName().split("")))
                        .map(String::toUpperCase)
                        .take(4)
                );


            mono.subscribe(System.out::println);
    return requestBody;
    }
}

POJO班级

package com.event.gateway.rest.controller;

import java.io.Serializable;

import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import com.fasterxml.jackson.annotation.JsonInclude;
import javax.xml.bind.annotation.XmlAccessType;
@JsonInclude(JsonInclude.Include.NON_NULL)
@XmlRootElement(name="sir")
@XmlAccessorType(XmlAccessType.FIELD)
public class Sir implements Serializable {

    private static final long serialVersionUID = 1L;
    @XmlElement(name ="firstName")
    private String firstName;

    @XmlElement(name ="lastName")
    private String lastName;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

}

邮递员样本请求

POST /hello HTTP/1.1
Host: localhost:8070
Content-Type: application/xml
Cache-Control: no-cache
Postman-Token: 2132d866-347e-5fcf-de00-2dc8f5f97ac0

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sir>
    <firstName>Jane Doe</firstName>
    <lastName>Peter</lastName>
</sir>

我收到500内部服务器错误作为响应。

非常感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

不确定原因,但我可以看到它使用Jaxb2XmlDecoder来解码XML有效负载,并且decodeToMono方法没有在那里实现。

要解决此问题,您可以将Flux<Sir>类型用作requestBody

答案 1 :(得分:0)

你能解释一下你想在控制器中实现什么目标吗?

此错误可能源于您在控制器方法中调用subscribe,有效消耗传入的Flux并同时返回。

作为一般规则,您不应在控制器中订阅Publisher

答案 2 :(得分:0)

正如KOrest所指出的那样,Jaxb2XmlDecoder没有实现decodeToMono,但现在通过SPR-16759修复了它。因此,只需升级到Spring Framework 5.0.6+ / Spring Boot 2.0.2+就可以避免报告的异常。

旁注:就像Brian Clozel一样,我不确定你想要实现什么,你可能不应该手动调用subscribe,而是返回输入的转换。如果您想要在不触发人工需求的情况下打印输出,可以使用doOnNext