![](/img/trans.png)
[英]TransactionRequiredException in spring webmvc framework
[英]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頭信息,因為produces
和setContentType
上面顯然沒有任何影響。 另外,由於圖像可能很大,因此我認為@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.