我有一个Spring应用程序,它使用带有WebMVC的JPA存储库,我正在尝试扩展它以支持图像。我可以上传图像并将它们存储在服务器端,但是当涉及到用客户端实际检索图像时,我实际上无法成功发送响应。
首先,这是我公开的客户端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
和{{ 1}}以上显然没有任何影响。此外,由于图片可能很大,我认为setContentType
注释是有保证的,并且只能与@Streaming
一起使用。
如果有帮助,这是我用来测试我的应用程序的代码:
Response
我已经在这里,现在,已经有几天了,而且我没有找到任何可以暗示如何克服上述问题的建议。我认为使用带有WebMVC的JPA存储库来访问静态文件存储的过程经常出现,但我还没有找到任何有用的东西。任何帮助将不胜感激。
由于
答案 0 :(得分:0)
尝试在Spring MVC设置中将 ByteArrayHttpMessageConverter 添加到转换器,并将方法的返回类型更改为 byte [] 。另外,请不要忘记添加 @ResponseBody 注释。
答案 1 :(得分:0)
您可以尝试以下操作:
@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);
}
如您所见,您需要图像的字节数组。但是,您也可以使用流。请参阅 Return a stream with Spring MVC's ResponseEntity 。
答案 2 :(得分:0)
好吧,这只是我能想到解决问题的最愚蠢的方式,我不认为这是一个真正的答案,但这是我唯一可以达到的目的。工作。出于某种原因,我的设置似乎绝对需要一个持久化实体,以便不出现JSON错误。在这种情况下,我在List<Byte>
周围构建了一个包装器(似乎即使是一个字节[]也不够好 - 它需要是可以用@ElementCollection
注释的东西。 。返回图像时,我将图像内容复制到刚刚提到的包装器中;在客户端,我提取存储的字节。然后我删除了持久的图像数据。
我知道这在所需的开销方面过于密集,并且可能不会在现实环境中工作,但正如我所说,这是我所拥有的。这种愚蠢超出了所有人的信念,但我已经放弃了试图找到正确的解决方案。
顺便说一句,如果有人想看看正确解决方案的原始尝试(没有上面提到的图像包装器),那就可以使用here