[英]HttpMediaTypeNotAcceptableException: Could not find acceptable representation
[英]HttpMediaTypeNotAcceptableException: Could not find acceptable representation - MediaType produces different results
使用 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
它會非常有效。 正如我所期望的那樣,它返回與該異常相關的異常和錯誤消息,但是我們需要為 SseEmitter 使用 TEXT_STREAM 並且我們的消費者期望這種類型的返回。 從我(有限的)理解 Spring 有一些神奇的 HttpConversion 發生在響應主體上,那么我需要做什么才能使用 products produces = MediaType.APPLICATION_JSON_STREAM_VALUE
返回異常? 我是否需要編寫自己的響應轉換器,但看起來可能......?
您沒有正確終止您的執行人。 對 shutdown 的調用不會執行您可能期望它執行的操作。 ExecutorService 的 javadoc 中的一個示例。
void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
通常,cachedThread 池應該是共享資源,不應在端點內初始化。 cachedThreadPool 的目的是利用線程重用並避免線程的失控創建。 如果你真的需要單線程使用newSingleThreadExecutor
我真的不明白你為什么在這里使用執行器。 它似乎沒有增加任何價值。 您只是在阻止您的請求處理程序線程在不同的線程中執行代碼,而它本來可以在原始線程中執行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.