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

如何通过Spring Rest获取二进制数据与JSON?求代码示例

用Spring Rest同时获取二进制数据与JSON的两种方案

没问题!我来给你分享两种实用的实现方式,帮你在Spring Rest接口里同时拿到二进制文件(比如PDF、图片)和附加的JSON信息~

方案一:响应头携带JSON元数据,响应体返回二进制数据

这种方式比较轻量,适合元数据内容不多的场景。咱们把JSON格式的附加信息放在HTTP响应头里,响应体直接返回二进制文件内容。

服务器端代码示例

import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.HashMap;
import java.util.Map;

@RestController
public class FileWithMetaController {

    private final ObjectMapper objectMapper = new ObjectMapper();

    @GetMapping("/download-with-meta")
    public ResponseEntity<Resource> downloadFileWithMetadata() throws Exception {
        // 1. 准备二进制文件(这里用classpath下的PDF为例)
        Resource pdfFile = new ClassPathResource("sample.pdf");

        // 2. 准备附加的JSON元数据
        Map<String, Object> metaData = new HashMap<>();
        metaData.put("fileId", "12345");
        metaData.put("fileName", "sample.pdf");
        metaData.put("fileSize", pdfFile.contentLength());
        metaData.put("description", "这是一个示例PDF文件");

        // 3. 把元数据转成JSON字符串,放进响应头
        String metaJson = objectMapper.writeValueAsString(metaData);
        HttpHeaders headers = new HttpHeaders();
        headers.add("X-File-Metadata", metaJson);
        headers.setContentType(MediaType.APPLICATION_PDF);
        headers.setContentDispositionFormData("attachment", pdfFile.getFilename());

        // 4. 返回响应
        return new ResponseEntity<>(pdfFile, headers, HttpStatus.OK);
    }
}

客户端代码示例(用RestTemplate)

import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.Map;

public class FileClient {

    public static void main(String[] args) throws Exception {
        RestTemplate restTemplate = new RestTemplate();
        String url = "http://localhost:8080/download-with-meta";

        ResponseEntity<Resource> response = restTemplate.exchange(
                url,
                HttpMethod.GET,
                null,
                Resource.class
        );

        // 1. 从响应头获取JSON元数据并解析
        String metaJson = response.getHeaders().getFirst("X-File-Metadata");
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Object> metaData = objectMapper.readValue(metaJson, Map.class);
        System.out.println("文件元数据:" + metaData);

        // 2. 获取二进制文件内容(这里可以保存到本地或者直接处理)
        Resource fileResource = response.getBody();
        if (fileResource != null) {
            // 示例:保存到本地
            // Files.copy(fileResource.getInputStream(), Paths.get("downloaded_sample.pdf"));
            System.out.println("文件内容已获取,长度:" + fileResource.contentLength());
        }
    }
}

方案二:Multipart响应,拆分二进制与JSON为不同Part

如果你的元数据比较复杂,或者更倾向于规范的多部分响应格式,可以用multipart/form-data类型,把二进制文件和JSON分别作为响应的两个Part。

服务器端代码示例

import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
public class MultipartFileController {

    @GetMapping(value = "/download-multipart", produces = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResponseEntity<MultiValueMap<String, Object>> downloadMultipart() {
        // 1. 准备二进制文件
        Resource pdfFile = new ClassPathResource("sample.pdf");

        // 2. 准备JSON元数据
        Map<String, Object> metaData = new HashMap<>();
        metaData.put("fileId", "67890");
        metaData.put("fileName", "sample_multipart.pdf");
        metaData.put("author", "StackExchange User");

        // 3. 构建Multipart响应体
        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        // 添加文件Part
        HttpHeaders fileHeaders = new HttpHeaders();
        fileHeaders.setContentType(MediaType.APPLICATION_PDF);
        body.add("file", new ResponseEntity<>(pdfFile, fileHeaders, HttpStatus.OK));
        // 添加元数据Part
        HttpHeaders metaHeaders = new HttpHeaders();
        metaHeaders.setContentType(MediaType.APPLICATION_JSON);
        body.add("metadata", new ResponseEntity<>(metaData, metaHeaders, HttpStatus.OK));

        // 4. 返回响应
        return new ResponseEntity<>(body, HttpStatus.OK);
    }
}

客户端代码示例(用RestTemplate)

import org.springframework.core.io.Resource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.Map;

public class MultipartFileClient {

    public static void main(String[] args) throws Exception {
        RestTemplate restTemplate = new RestTemplate();
        String url = "http://localhost:8080/download-multipart";

        ResponseEntity<MultiValueMap<String, Object>> response = restTemplate.exchange(
                url,
                HttpMethod.GET,
                null,
                (Class<MultiValueMap<String, Object>>) (Class<?>) MultiValueMap.class
        );

        MultiValueMap<String, Object> body = response.getBody();
        if (body != null) {
            // 1. 解析元数据Part
            ResponseEntity<Map> metaResponse = (ResponseEntity<Map>) body.getFirst("metadata");
            Map<String, Object> metaData = metaResponse.getBody();
            System.out.println("Multipart元数据:" + metaData);

            // 2. 解析文件Part
            ResponseEntity<Resource> fileResponse = (ResponseEntity<Resource>) body.getFirst("file");
            Resource fileResource = fileResponse.getBody();
            if (fileResource != null) {
                System.out.println("Multipart文件长度:" + fileResource.contentLength());
                // 保存文件逻辑...
            }
        }
    }
}

小提醒

  • 方案一中,如果JSON元数据包含特殊字符,建议对JSON字符串做Base64编码后再放入响应头,避免解析异常。
  • 方案二中,确保客户端和服务器端都正确处理multipart/form-data类型的响应,RestTemplate默认支持这种类型的解析。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:34:33