簡體   English   中英

Spring + JPA + WebMVC:返回JPEG

[英]Spring + JPA + WebMVC: Returning a JPEG

我有一個Spring應用程序,該應用程序將JPA存儲庫與WebMVC結合使用,並且正在嘗試對其進行擴展以提供圖像支持。 我可以上傳圖像並將其存儲在服務器端,但是當涉及到與客戶端實際檢索圖像時,我實際上無法成功發送響應。

首先,這是我公開的客戶端API:

@Streaming
@GET(PATIENT_EXTRA_PATH + "/{id}" + GET_IMAGE_RELPATH)
public Response getImageData(@Path(ID) long id, @Query(IMAGE_FILE) String imageFile);

這是我第一次嘗試實現:

@RequestMapping(value = PainManagementSvcApi.PATIENT_EXTRA_PATH + "/{id}" +
        PainManagementSvcApi.GET_IMAGE_RELPATH, method = RequestMethod.GET,
        produces = MediaType.IMAGE_JPEG_VALUE)
public HttpServletResponse getImageData(@PathVariable(PainManagementSvcApi.ID) long id,
        @RequestParam(PainManagementSvcApi.IMAGE_FILE) String imageFile,
        Principal principal, HttpServletResponse response) {
    // Do some stuff to ensure image availability and access

    // All of this works
    response.setContentType("image/jpeg");
    imageFileManager.copyImageData(imageFile, response.getOutputStream());
    response.setStatus(HttpServletResponse.SC_OK);

    // Return the response
    return response;
}

但是,該方法在測試時會產生以下異常:

javax.servlet.ServletException:無法解析名稱為“ dispatcherServlet”的servlet中名稱為“ extra / 1 / image”的視圖

環顧了一下之后,我認為我可能需要@ResponseBody注釋,如下所示:

@RequestMapping(value = PainManagementSvcApi.PATIENT_EXTRA_PATH + "/{id}" +
        PainManagementSvcApi.GET_IMAGE_RELPATH, method = RequestMethod.GET,
        produces = MediaType.IMAGE_JPEG_VALUE)
public HttpServletResponse getImageData(@PathVariable(PainManagementSvcApi.ID) long id,
        @RequestParam(PainManagementSvcApi.IMAGE_FILE) String imageFile,
        Principal principal, HttpServletResponse response) {
    // Same code as before
}

但是,添加@ResponseBody與我擁有的工作視頻示例(使用Spring,但不使用JPA存儲庫或WebMVC)發生沖突,並產生以下異常:

org.springframework.web.HttpMediaTypeNotAcceptableException:找不到可接受的表示形式

除了使用Response返回值之外,我還嘗試重新播放FileSystemResource ,但這會產生JSON錯誤,如下所示:

預期為BEGIN_OBJECT,但位於第1行第1列的STRING

因為我只是想回的圖像,我也不會覺得JSON是必要的,但我無法弄清楚如何去除JSON頭信息,因為producessetContentType上面顯然沒有任何影響。 另外,由於圖像可能很大,因此我認為@Streaming批注是必要的,並且只能與Response一起使用。

如果有幫助,下面是我用來測試應用程序的代碼:

Response response = user.getImageData(extra.getId(), fileName);
assertEquals(HttpStatus.SC_OK, response.getStatus());
InputStream imageStream = response.getBody().in();
byte[] retrievedFile = IOUtils.toByteArray(imageStream);
byte[] originalFile = IOUtils.toByteArray(new FileInputStream(images[index++]));
assertTrue(Arrays.equals(originalFile, retrievedFile));

我已經在這里待了幾天,但沒有發現任何建議可以解決上述問題的方法。 我認為使用帶有WebMVC的JPA存儲庫來控制對靜態文件存儲的訪問經常會出現,但是我還沒有找到有用的東西。 任何幫助,將不勝感激。

謝謝

嘗試在Spring MVC設置中將ByteArrayHttpMessageConverter添加到轉換器中,然后將方法的返回類型更改為byte [] 同樣不要忘記添加@ResponseBody注釋。

您可以嘗試以下方法:

@RequestMapping(value = PATIENT_EXTRA_PATH + "/{id}" + GET_IMAGE_RELPATH, 
                method = RequestMethod.GET)
public ResponseEntity<byte[]> getImageData(@PathVariable(PainManagementSvcApi.ID) long id,
        @RequestParam(PainManagementSvcApi.IMAGE_FILE) String imageFile,
        Principal principal, HttpServletResponse response) {

    // Do some stuff to ensure image availability and access

    response.setContentType("image/jpeg");

    // image to byte array
    byte[] contents = imageFileManager.copyImageData(imageFile);

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.parseMediaType("image/jpeg"));
    return new ResponseEntity<byte[]>(contents, headers, HttpStatus.OK);
}

如您所見,您需要一個圖像字節數組。 但是,您也可以使用流。 請參閱使用Spring MVC的ResponseEntity返回流

好的,這只是我想出的解決問題的最愚蠢的方式,我認為這不是一個真正的答案,但這是我唯一可以工作的方法。 由於某種原因,我的設置似乎絕對需要一個持久的實體,以免出現JSON錯誤。 在這種情況下,我圍繞List<Byte>構建了一個包裝器(似乎即使byte []也不夠好-它需要使用@ElementCollection進行注釋)。 返回圖像時,我將圖像內容復制到剛才提到的包裝器中; 在客戶端,我提取存儲的字節。 然后,我刪除了保留的圖像數據。

我知道這在所需的開銷方面過於繁瑣,可能無法在現實的環境中工作,但是正如我所說的,這就是我所擁有的。 這真是愚蠢至極,但是我已經放棄了尋找正確解決方案的嘗試。

順便說一句,如果有人想看看嘗試正確解決方案的原始嘗試(沒有上述Image wrapper),可以在這里找到

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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