2016-12-09 43 views
1

我有一個休息API在春天生成和下載PDF文件。控制器definitation如下 -春天 - 無法發送API返回錯誤消息ByteArrayResource

@RequestMapping(
     value = "/foo/bar/pdf", 
     method = RequestMethod.GET, 
     produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) 
@ResponseBody 
@Nullable 
public ByteArrayResource downloadPdf(@RequestParam int userId) { 
    byte[] result = null; 
    ByteArrayResource byteArrayResource = null; 

    result = service.generatePdf(userId); 

    if (result != null) { 
     byteArrayResource = new ByteArrayResource(result); 
    } 

    return byteArrayResource; 
} 

我用傑克遜JSON處理JSON,並有一個異常處理程序ControllerAdvice。問題是,當這個API產生一個異常,我返回一個自定義的異常類(包含消息和一個額外的字段)。

正如我已經指定produces = MediaType.APPLICATION_OCTET_STREAM_VALUE這個自定義類也試圖被轉換爲一個八位字節流由春,它失敗併產生HttpMediaTypeNotAcceptableException: Could not find acceptable representation

我試過this#1的問題,特別是解決this answer,但它仍然失敗。此解決方案以及其他更改建議從@RequestMapping中刪除produces部分,但是當我調試到AbstractMessageConverterMethodProcessor.getProducibleMediaTypes時,它僅檢測到application/json作爲可用響應介質類型。

TL;博士 我怎麼能有這樣的API返回成功的文件和正確的錯誤返回自定義異常類的JSON表示。

回答

1

嘗試實現你的行動

@RequestMapping(
    value = "/foo/bar/pdf", 
    method = RequestMethod.GET) 
@ResponseBody 
public HttpEntity<byte[]> downloadPdf(@RequestParam int userId) { 
byte[] result = service.generatePdf(userId); 

HttpHeaders headers = new HttpHeaders(); 

if (result != null) { 
    headers.setContentType(new MediaType("application", "pdf")); 
    headers.set("Content-Disposition", "inline; filename=export.pdf"); 
    headers.setContentLength(result.length); 

    return new HttpEntity(result, headers); 
} 

return new HttpEntity<>(header) 
} 

關於例外處理,例如,你可能會拋出YourCustomError並與@ControllerAdvice註釋與@ExceptionHandler(YourCustomError.class)的方法註解控制器和使用它。

0

我有類似的代碼相同的問題。我只是從我的@PostMapping取出produces屬性,我能夠返回文件或JSON(當API有一些錯誤):

@Override 
@PostMapping 
public ResponseEntity<InputStreamResource> generate(
     @PathVariable long id 
) { 
    Result result = service.find(id); 

    return ResponseEntity 
      .ok() 
      .cacheControl(CacheControl.noCache()) 
      .contentLength(result.getSize()) 
      .contentType(MediaType.parseMediaType(MediaType.APPLICATION_PDF_VALUE)) 
      .body(new InputStreamResource(result.getFile())); 
} 

當某些錯誤發生時,我有一個@ExceptionHandler關心的是:

@ExceptionHandler 
public ResponseEntity<ApiErrorResponse> handleApiException(ApiException ex) { 
    ApiErrorResponse error = new ApiErrorResponse(ex); 
    return new ResponseEntity<>(error, ex.getHttpStatus()); 
}