有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Spring MVC:如何在@ResponseBody中返回图像?

我正在从数据库获取图像数据(如byte[])。如何在@ResponseBody中返回此图像

编辑

我使用HttpServletResponse作为方法参数,在没有@ResponseBody的情况下完成了这项工作:

@RequestMapping("/photo1")
public void photo(HttpServletResponse response) throws IOException {
    response.setContentType("image/jpeg");
    InputStream in = servletContext.getResourceAsStream("/images/no_image.jpg");
    IOUtils.copy(in, response.getOutputStream());
}

@ResponseBody与注册的org.springframework.http.converter.ByteArrayHttpMessageConverter转换器一起作为@Sid使用对我来说不起作用:(

@ResponseBody
@RequestMapping("/photo2")
public byte[] testphoto() throws IOException {
    InputStream in = servletContext.getResourceAsStream("/images/no_image.jpg");
    return IOUtils.toByteArray(in);
}

共 (6) 个答案

  1. # 1 楼答案

    我更喜欢这个:

    private ResourceLoader resourceLoader = new DefaultResourceLoader();
    
    @ResponseBody
    @RequestMapping(value = "/{id}",  produces = "image/bmp")
    public Resource texture(@PathVariable("id") String id) {
        return resourceLoader.getResource("classpath:images/" + id + ".bmp");
    }
    

    将媒体类型更改为现有的图像格式

  2. # 2 楼答案

    除了这里的几个答案之外,还有一些建议(Spring 4.1)

    如果您的WebMvcConfig中没有配置任何messageconverters,那么在@ResponseBody中配置ResponseEntity效果很好

    如果你这样做了,也就是说,你有一个MappingJackson2HttpMessageConverter配置(像我一样),使用ResponseEntity返回一个org.springframework.http.converter.HttpMessageNotWritableException

    在这种情况下,唯一有效的解决方案是将byte[]包装在@ResponseBody中,如下所示:

    @RequestMapping(value = "/get/image/{id}", method=RequestMethod.GET, produces = MediaType.IMAGE_PNG_VALUE)
    public @ResponseBody byte[] showImageOnId(@PathVariable("id") String id) {
        byte[] b = whatEverMethodUsedToObtainBytes(id);
        return b;
    }
    

    在这种情况下,请记住在WebMvcConfig中正确配置messageconverters(并添加ByteArrayHttpMessageConverer),如下所示:

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(mappingJackson2HttpMessageConverter());
        converters.add(byteArrayHttpMessageConverter());
    }
    
    @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setObjectMapper(objectMapper);
        return converter;
    }
    
    @Bean
    public ByteArrayHttpMessageConverter byteArrayHttpMessageConverter() {
        ByteArrayHttpMessageConverter arrayHttpMessageConverter = new ByteArrayHttpMessageConverter();
        arrayHttpMessageConverter.setSupportedMediaTypes(getSupportedMediaTypes());
        return arrayHttpMessageConverter;
    }
    
    private List<MediaType> getSupportedMediaTypes() {
        List<MediaType> list = new ArrayList<MediaType>();
        list.add(MediaType.IMAGE_JPEG);
        list.add(MediaType.IMAGE_PNG);
        list.add(MediaType.APPLICATION_OCTET_STREAM);
        return list;
    }
    
  3. # 3 楼答案

    使用Spring 4.1及以上版本,您可以非常简单地返回几乎任何内容(如图片、PDF、文档、罐子、拉链等),而无需任何额外的依赖项。例如,以下方法可以从MongoDB GridFS返回用户的个人资料图片:

    @RequestMapping(value = "user/avatar/{userId}", method = RequestMethod.GET)
    @ResponseBody
    public ResponseEntity<InputStreamResource> downloadUserAvatarImage(@PathVariable Long userId) {
        GridFSDBFile gridFsFile = fileService.findUserAccountAvatarById(userId);
    
        return ResponseEntity.ok()
                .contentLength(gridFsFile.getLength())
                .contentType(MediaType.parseMediaType(gridFsFile.getContentType()))
                .body(new InputStreamResource(gridFsFile.getInputStream()));
    }
    

    需要注意的是:

    • 以InputStreamResource作为返回类型的响应性

    • ResponseEntity builder风格创建

    使用这种方法,您不必担心HttpServletResponse中的自动连接、引发IOException或复制流数据

  4. # 4 楼答案

    除了注册ByteArrayHttpMessageConverter之外,您可能还希望使用ResponseEntity而不是@ResponseBody。以下代码适用于我:

    @RequestMapping("/photo2")
    public ResponseEntity<byte[]> testphoto() throws IOException {
        InputStream in = servletContext.getResourceAsStream("/images/no_image.jpg");
    
        final HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.IMAGE_PNG);
    
        return new ResponseEntity<byte[]>(IOUtils.toByteArray(in), headers, HttpStatus.CREATED);
    }
    
  5. # 5 楼答案

    通过使用Spring 3.1。x和3.2。x、 你应该这样做:

    控制器方法:

    @RequestMapping("/photo2")
    public @ResponseBody byte[] testphoto() throws IOException {
        InputStream in = servletContext.getResourceAsStream("/images/no_image.jpg");
        return IOUtils.toByteArray(in);
    }
    

    以及servlet上下文中的mvc注释。xml文件:

    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>image/jpeg</value>
                        <value>image/png</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>
    
  6. # 6 楼答案

    如果您使用的是Spring版本的3.1或更新版本,那么可以在@RequestMapping注释中指定“products”。下面的例子对我来说是现成的。如果启用了web mvc(@EnableWebMvc),则不需要寄存器转换器或其他任何东西

    @ResponseBody
    @RequestMapping(value = "/photo2", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE)
    public byte[] testphoto() throws IOException {
        InputStream in = servletContext.getResourceAsStream("/images/no_image.jpg");
        return IOUtils.toByteArray(in);
    }