Spring + JPA + WebMVC:返回JPEG

时间:2014-11-11 21:49:41

标签: java spring spring-mvc jpa

我有一个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存储库来访问静态文件存储的过程经常出现,但我还没有找到任何有用的东西。任何帮助将不胜感激。

由于

3 个答案:

答案 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