You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot API返回多张图片异常及报错问题求助

如何在Spring Boot中返回多张可直接显示的图片?

我开发了一个Spring Boot方法用于返回多张图片数据,但当前返回的是JSON格式的图片字节数据,我希望响应是可正常显示的图片。

最初的实现(返回JSON格式字节数组)

public List<ResponseEntity<byte[]>> viewImage(@PathVariable("id") Long id) throws NoSuchElementException, NotFoundException {
    List<byte[]> bytes = productService.showImage(id);
    List<ResponseEntity<byte[]>> responseEntities = new ArrayList<>();

    for (byte[] imageBytes : bytes) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.IMAGE_PNG);

        ResponseEntity<byte[]> responseEntity = ResponseEntity.ok()
                .headers(headers)
                .body(imageBytes);

        responseEntities.add(responseEntity);
    }

    return responseEntities;
}

这个方法的响应是JSON格式的字节数组列表,无法直接显示为图片。

尝试使用Multipart格式但报错

我尝试改用multipart/mixed格式返回,代码如下:

public ResponseEntity<List<ResponseEntity<InputStreamResource>>> viewImages() {
    List<byte[]> imageBytesList = getImageBytesList();

    if (imageBytesList.isEmpty()) {
        return ResponseEntity.notFound().build();
    }

    List<ResponseEntity<InputStreamResource>> responseEntities = new ArrayList<>();

    for (byte[] imageBytes : imageBytesList) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.IMAGE_PNG);
        headers.setContentLength(imageBytes.length);

        InputStreamResource inputStreamResource = new InputStreamResource(new ByteArrayInputStream(imageBytes));
        ResponseEntity<InputStreamResource> responseEntity = ResponseEntity.ok()
                .headers(headers)
                .body(inputStreamResource);

        responseEntities.add(responseEntity);
    }

    HttpHeaders multipartHeaders = new HttpHeaders();
    multipartHeaders.setContentType(MediaType.MULTIPART_MIXED);

    return ResponseEntity.ok()
            .headers(multipartHeaders)
            .body(responseEntities);
}

但运行时出现错误:

org.springframework.http.converter.HttpMessageNotWritableException: No converter for [class java.util.ArrayList] with preset Content-Type 'multipart/mixed'

解决方法

问题原因

Spring Boot默认没有提供将List<ResponseEntity>转换为multipart/mixed响应的转换器,直接返回列表不符合multipart响应的规范。

正确实现:使用MultipartBodyBuilder构建多部分响应

Spring提供了MultipartBodyBuilder来构建符合multipart规范的响应体,每个部分对应一张图片。修正后的代码如下:

import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.multipart.MultipartBodyBuilder;
import java.util.ArrayList;
import java.util.List;

@GetMapping("/images/{id}")
public ResponseEntity<?> viewImage(@PathVariable("id") Long id) throws NoSuchElementException, NotFoundException {
    List<byte[]> imageBytesList = productService.showImage(id);
    
    if (imageBytesList.isEmpty()) {
        return ResponseEntity.notFound().build();
    }

    MultipartBodyBuilder builder = new MultipartBodyBuilder();
    // 遍历图片字节数组,逐个添加到multipart体中
    for (int index = 0; index < imageBytesList.size(); index++) {
        byte[] imageBytes = imageBytesList.get(index);
        HttpHeaders partHeaders = new HttpHeaders();
        partHeaders.setContentType(MediaType.IMAGE_PNG);
        
        // 为每个图片部分设置唯一名称,方便前端识别处理
        builder.part("image-" + index, imageBytes)
                .headers(partHeaders);
    }

    return ResponseEntity.ok()
            .contentType(MediaType.MULTIPART_MIXED)
            .body(builder.build());
}

替代方案(更推荐)

如果前端支持,更符合REST规范的做法是返回图片的URL列表,让前端逐个请求单张图片:

@GetMapping("/image-urls/{id}")
public ResponseEntity<List<String>> getImageUrls(@PathVariable("id") Long id) {
    // 假设每张图片有对应的访问URL,比如通过id和图片索引生成
    List<String> imageUrls = new ArrayList<>();
    List<byte[]> images = productService.showImage(id);
    for (int i = 0; i < images.size(); i++) {
        imageUrls.add("/api/images/" + id + "/" + i);
    }
    return ResponseEntity.ok(imageUrls);
}

// 单独的单张图片返回接口
@GetMapping("/images/{id}/{index}")
public ResponseEntity<byte[]> getSingleImage(@PathVariable("id") Long id, @PathVariable("index") int index) {
    List<byte[]> images = productService.showImage(id);
    if (index < 0 || index >= images.size()) {
        return ResponseEntity.notFound().build();
    }
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.IMAGE_PNG);
    return ResponseEntity.ok()
            .headers(headers)
            .body(images.get(index));
}

这种方式更灵活,也便于前端缓存和单独处理每张图片。

内容的提问来源于stack exchange,提问作者Aditya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 18:07:03