Flux.error即使抛出异常也会返回200 HTTP代码

3

我正在开发一个与Spring Boot(v2 M3)和Spring WebFlux相关的项目。在编码过程中,我发现我的微服务在返回一个flux时会返回一个 Http 200状态码,而实际上出现了错误。

因此,我进行了简单的测试: 我创建了一个简单的控制器。

@RestController
@RequestMapping(value = "/test")
public class TestController {

   @GetMapping(value = "/errors")
   public Flux<Object> getErrors() {
       return Flux.error(new RuntimeException("test"));
   }
}

通过一个简单的异常处理程序:

@ControllerAdvice
public class TestExceptionHandler {

     private static final Logger LOGGER = LoggerFactory.getLogger(TestExceptionHandler.class);

     @ExceptionHandler(value = { RuntimeException.class })
     public ResponseEntity<String> handleServerError(final RuntimeException e) {
        LOGGER.error(e.getMessage(), e);
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
     }
}

我使用webTestClient在集成测试中测试结果:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource("classpath:test.properties")
public class TestErrorsIT {

    @Autowired
    private WebTestClient webTestClient;

    @Test
    public void getErrors() {

        this.webTestClient.get().uri("/test/errors").accept(MediaType.APPLICATION_STREAM_JSON).exchange().expectStatus()
                        .is5xxServerError();
    }
}

因此,我的测试失败了,因为返回错误流的控制器返回的是200状态码而不是503状态码(异常日志“test”在我的控制台中被很好地跟踪)。你知道为什么吗?

java.lang.AssertionError: 响应状态值范围为200 预期值:但实际却是:

GET http://localhost:54432/test/errors WebTestClient-Request-Id: [1] Accept: [application/stream+json]

无内容

< 200 OK < Content-Type: [application/stream+json] < Transfer-Encoding: [chunked] < Date: [Fri, 03 Nov 2017 09:42:53 GMT]

内容暂时不可用


你能否创建一个示例项目来说明这个问题?我尝试复制/粘贴您的代码来重现这个问题,但无法重现。 - Brian Clozel
你好Brian,感谢你的回答。我创建了一个简单的项目并没有复制这个问题。今天经过更多的分析,我发现我们项目中使用的“spring-cloud-starter-eureka”有“spring-boot-starter-web”的依赖,并提供“spring-webmvc”。在排除“spring-boot-starter-web”之后,一切正常。 不幸的是,“spring-webmvc”是swagger(springfox)工作所必需的。所以我们有一个可用的微服务但失去了swagger支持... - Manuel KRUPA
Spring Reactive的Springfox支持链接: https://github.com/springfox/springfox/issues/1773 - Manuel KRUPA
你应该把这个作为你问题的答案。这对其他 Stack Overflow 成员会很有用! - Brian Clozel
1个回答

1
在这个例子中,该应用程序依赖于spring-cloud-starter-eureka,而它本身对spring-boot-starter-web有一个传递依赖。
spring-boot-starter-web添加到Spring Boot应用程序中会将其转换为Spring MVC应用程序,这解释了这种行为。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接