【发布时间】:2020-09-04 15:37:32
【问题描述】:
使用 Spring MVC,我有一个控制器,其端点返回 SseEmitter。
@GetMapping(path = "/accept/{amount}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
@ApiResponses({
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "409", description = "BUSY", content = @Content(schema = @Schema(implementation = MyErrorClass.class))),
@ApiResponse(responseCode = "500", description = "UNEXPECTED_ERROR", content = @Content(schema = @Schema(implementation = MyErrorClass.class)))
})
public SseEmitter accept(@Parameter(description = "Amount to accept") @PathVariable double amount) throws MyException {
ExecutorService service = Executors.newCachedThreadPool();
SseEmitter emitter = new SseEmitter();
myService.accept(amount);
service.execute(() -> {
while(myService.inAcceptanceState()) {
try {
emitter.send(myService.getCurrentAmount());
Thread.sleep(1000);
} catch (InterruptedException | IOException ex) {
emitter.completeWithError(ex);
}
}
try {
emitter.send(myService.getCurrentAmount());
emitter.complete();
} catch (IOException e) {
emitter.completeWithError(e);
}
});
service.shutdown();
return emitter;
}
在上述代码的情况下,accept() 方法在第一次调用完成之前第二次调用时预计会抛出 400 错误。截至目前,我得到以下信息:
2020-09-03 15:22:14.105 WARN 480 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Failure in @ExceptionHandler com.mydomain.common.ExceptionController#handleMyException(Exception)
org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
这不会使我的 springboot 服务崩溃,但调用不会终止,因此会导致明显的问题。我注意到如果我更改为produces = MediaType.APPLICATION_JSON_STREAM_VALUE,它会非常有效。正如我所期望的那样,它返回与该异常相关的异常和错误消息,但是我们需要将 TEXT_STREAM 用于 SseEmitter 并且我们的消费者期望这种类型的返回。根据我的(有限的)理解,Spring 在响应体中发生了一些神奇的 HttpConversion,那么我需要做什么才能使用produces = MediaType.APPLICATION_JSON_STREAM_VALUE 返回异常?我是否需要编写自己的响应转换器,但看起来...?
【问题讨论】:
-
看来这个问题和我遇到的类似,但没有解决办法:github.com/spring-projects/spring-framework/issues/23821 我想@ExceptionHandler 可以用,但不确定是否那么简单
标签: java spring-boot spring-mvc media-type