28

我创建了一个看起来像这样的 RestController:

@RestController
public class GreetingController {

    @RequestMapping(value = "/greetings", method = RequestMethod.GET)
    public Mono<Greeting> greeting(HttpServletRequest request) {

        return Mono.just(new Greeting("Hello..." + request.toString()));
    }
}

不幸的是,当我尝试点击“问候”端点时,我得到了一个例外:

java.lang.IllegalStateException:[org.apache.catalina.servlet4preview.http.HttpServletRequest] 类型的参数 [0] 没有解析器

我在用

compile('org.springframework.boot.experimental:spring-boot-starter-web-reactive')

如何解决这个问题?

链接到完整的堆栈跟踪。链接到 build.gradle

- - - - - 编辑 - - - - -

使用界面。现在得到:

java.lang.IllegalStateException:方法上类型 [javax.servlet.http.HttpServletRequest] 的参数 [0] 没有解析器(其余部分相同)

4

2 回答 2

38

永远不应该在 Spring Reactive Web 应用程序中使用 Servlet API。这不受支持,这使您的应用程序依赖于容器,而 Spring Web Reactive 可以与非 Servlet 运行时(例如 Netty)一起使用。

相反,您应该使用 Spring 提供的 HTTP API;这是您的代码示例,有一些更改:

import org.springframework.http.server.reactive.ServletServerHttpRequest;

@RestController
public class GreetingController {

    @GetMapping("/greetings")
    public Mono<Greeting> greeting(ServerHttpRequest request) {

        return Mono.just(new Greeting("Hello..." + request.getURI().toString()));
    }
}

您可以注入ServerWebExchange或直接注入ServerHttpRequest/ ServerHttpResponse

于 2016-11-04T13:35:16.870 回答
4

我深入调用层次结构,发现 在包org.springframework.web.reactive.result.method中有这个类InvocableHandlerMethod ,它有:

private List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();

这个类中有一个resolveArguments()方法,调用它来“解析参数”。不幸的是,此列表中没有 javax.servlet.http.HttpServletRequest的解析器。

然而,有一个ServerWebExchangeArgumentResolver能够解析ServletServerHttpRequest,我可以从中提取HttpServletRequest。是啊……

所以端点看起来像:

@RequestMapping(value = "/greetings", method = RequestMethod.GET)
public Mono<Greeting> greeting(ServletServerHttpRequest servletServerHttpRequest) {

    HttpServletRequest httpServletRequest = servletServerHttpRequest.getServletRequest();
    .
    .
    .
}

重要的是ServletServerHttpRequest来自包org.springframework.http.server.reactive

于 2016-11-01T14:24:45.353 回答