Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring+JPA+WebMVC:返回JPEG_Java_Spring_Spring Mvc_Jpa - Fatal编程技术网

Java Spring+JPA+WebMVC:返回JPEG

Java Spring+JPA+WebMVC:返回JPEG,java,spring,spring-mvc,jpa,Java,Spring,Spring Mvc,Jpa,我有一个使用JPA存储库和WebMVC的Spring应用程序,我正在尝试扩展它以获得图像支持。我可以上传图像并将其存储在服务器端,但当涉及到使用客户端实际检索图像时,我实际上无法成功发送响应 首先,这是我公开的客户端API: @Streaming @GET(PATIENT_EXTRA_PATH + "/{id}" + GET_IMAGE_RELPATH) public Response getImageData(@Path(ID) long id, @Query(IMAGE_FILE) Stri

我有一个使用JPA存储库和WebMVC的Spring应用程序,我正在尝试扩展它以获得图像支持。我可以上传图像并将其存储在服务器端,但当涉及到使用客户端实际检索图像时,我实际上无法成功发送响应

首先,这是我公开的客户端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:找不到可接受的表示形式

除了使用响应返回值外,我还尝试重新调用FileSystemResource,但这会产生如下JSON错误:

@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);
}
应为BEGIN_对象,但在第1行第1列为字符串

由于我只是试图返回一个图像,我认为不需要JSON,但我不知道如何删除JSON头信息,因为上面的products和setContentType显然没有任何影响。此外,由于图像可能很大,我认为@Streaming注释是有保证的,并且只能与响应一起使用

如果有帮助,下面是我用来测试我的应用程序的代码:

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);
}

如您所见,您需要图像的字节数组。但是,您也可以使用流。看。

好吧,这是我能想到的解决我的问题的最愚蠢的方法,我不认为这是一个真正的答案,但这是我唯一能做的事情。出于某种原因,我的设置似乎绝对需要一个持久化实体,以避免出现JSON错误。在这种情况下,我围绕一个列表构建了一个包装器——似乎连字节[]都不够好——它必须是可以用@ElementCollection注释的东西。返回图像时,我将图像内容复制到刚才提到的包装器中;在客户端,我提取存储的字节。然后我擦除持久化的图像数据

我知道这在所需的开销方面过于密集,在现实环境中可能不起作用,但是,正如我所说的,这就是我所拥有的一切。这是难以置信的愚蠢,但我已经放弃了寻找正确的解决办法


顺便说一句,如果有人想看一看上面提到的无图像包装器的正确解决方案的原始尝试,这是可用的

不幸的是,这导致了与我在FileSystemResource方法中遇到的相同的客户机问题;即:java.lang.IllegalStateException:应为BEGIN_对象,但在第1行第1列为字符串。不过,它确实会清除服务器端的异常。我刚刚意识到,问题可能不再出现在服务器端,而是在您提出建议后出现在客户端。顺便说一句,感谢您提供了到InputStreamResource讨论的链接。那么,我认为客户端需要对RestAdapter.Builder.setConverter执行一些操作,对吗?您在测试中使用的是哪个客户端库?我只是使用一个实现API的Apache HttpClient。这就是你要问的吗?如果有帮助的话,您不介意看一看,我可以简单地打包服务器和测试项目供您审阅不幸的是,这导致了我在使用FileSystemResource方法时遇到的客户机问题;即:java.lang.IllegalStateException:应为BEGIN_对象,但在第1行第1列为字符串。但是,它确实会清除服务器端的异常。要注册Bean,除了:@Bean public ByteArrayHttpMessageConverter ByteArrayHttpMessageConverter{…}您还应该在客户端添加相同的转换器谢谢您的建议。我对Spring还是新手,所以我不确定如何在客户端的默认值之外添加额外的转换。为了清楚起见,我在上发布了一个单独的问题。似乎您正在使用Retrof
客户端的it库。您可以尝试将其添加到界面@Headers{Content Type:image/jpeg}。之后,您可以使用response.getBody.in获取inputstream。然后,您可以使用一些辅助方法将此InputStream转换为字节数组。您可以通过改装文件支持来访问此链接。我建议您的服务器端控制器应该返回字节[]。如果将Content Type:image/jpeg添加到客户端,则还应在服务器端设置此头,如上面Paul Vargas所述。如果您不在服务器端设置此选项,它应该具有一些默认的内容类型,如application/octet stream或类似的smth。您可以在浏览器上使用类似Firebug的工具查看响应标题。如果客户端与服务器端发送的头匹配,它应该能够处理响应。