簡體   English   中英

HttpMediaTypeNotAcceptableException:找不到可接受的表示 - MediaType 產生不同的結果

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM