HoRain云--RestTemplate使用文件参数的高级应用案例

  

🎬 HoRain 云小助手个人主页

⛺️生活的理想,就是为了理想的生活!


⛳️ 推荐

前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。

目录

⛳️ 推荐

1. 多文件上传 + 混合表单参数

2. 动态设置文件元数据

3. 大文件分块上传

4. 处理文件上传响应及异常

5. 自定义请求头与认证

关键注意事项



1. 多文件上传 + 混合表单参数

上传多个文件并附带其他表单参数(如用户ID、描述信息),且自定义文件名和 Content-Type。

import org.springframework.core.io.FileSystemResource;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

public class AdvancedFileUpload {

    public void uploadFilesWithMetadata() {
        RestTemplate restTemplate = new RestTemplate();
        String url = "http://api.example.com/upload";

        // 构造 multipart/form-data 请求体
        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        
        // 添加文件参数(多个文件)
        body.add("files", new FileSystemResource("path/to/file1.jpg") {
            @Override
            public String getFilename() {
                return "custom-name-1.jpg"; // 自定义文件名
            }
        });
        body.add("files", new FileSystemResource("path/to/file2.pdf"));

        // 添加普通表单参数
        body.add("userId", "12345");
        body.add("description", "Project documents");

        // 发送请求(自动处理 Content-Type 为 multipart/form-data)
        String response = restTemplate.postForObject(url, body, String.class);
        System.out.println("Response: " + response);
    }
}

2. 动态设置文件元数据

通过 InputStreamResourceByteArrayResource 动态设置文件的 Content-Type 和文件名。

import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import java.io.ByteArrayInputStream;

public class FileMetadataExample {

    public void uploadWithDynamicMetadata() {
        RestTemplate restTemplate = new RestTemplate();
        String url = "http://api.example.com/upload";

        // 从字节数组或流构造文件资源
        byte[] fileData = "Hello, World!".getBytes();
        ByteArrayResource resource = new ByteArrayResource(fileData) {
            @Override
            public String getFilename() {
                return "dynamic-file.txt";
            }
        };

        // 自定义 Content-Type
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.TEXT_PLAIN);

        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        body.add("file", new HttpEntity<>(resource, headers));

        // 发送请求
        String response = restTemplate.postForObject(url, body, String.class);
    }
}

3. 大文件分块上传

处理大文件时,分块上传以减少内存占用,并支持断点续传。

import org.springframework.core.io.FileSystemResource;
import org.springframework.util.StreamUtils;
import java.io.File;
import java.io.FileInputStream;

public class ChunkedFileUpload {

    public void uploadLargeFileInChunks() throws Exception {
        RestTemplate restTemplate = new RestTemplate();
        String url = "http://api.example.com/upload-chunk";
        File largeFile = new File("path/to/large-file.zip");
        final int CHUNK_SIZE = 5 * 1024 * 1024; // 5MB per chunk

        try (FileInputStream fis = new FileInputStream(largeFile)) {
            byte[] buffer = new byte[CHUNK_SIZE];
            int bytesRead;
            int chunkNumber = 0;

            while ((bytesRead = fis.read(buffer)) != -1) {
                // 截取实际读取的字节(避免最后一块填充空数据)
                byte[] chunkData = new byte[bytesRead];
                System.arraycopy(buffer, 0, chunkData, 0, bytesRead);

                MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
                body.add("chunk", new ByteArrayResource(chunkData) {
                    @Override
                    public String getFilename() {
                        return largeFile.getName() + ".part" + chunkNumber;
                    }
                });
                body.add("totalChunks", (int) Math.ceil(largeFile.length() / (double) CHUNK_SIZE));
                body.add("chunkNumber", chunkNumber);
                body.add("originalFilename", largeFile.getName());

                restTemplate.postForObject(url, body, String.class);
                chunkNumber++;
            }
        }
    }
}

4. 处理文件上传响应及异常

捕获上传过程中的异常,并解析服务器返回的 JSON 数据。

import org.springframework.http.ResponseEntity;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;

public class ErrorHandlingExample {

    public void uploadWithErrorHandling() {
        RestTemplate restTemplate = new RestTemplate();
        String url = "http://api.example.com/upload";

        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        body.add("file", new FileSystemResource("invalid-file.txt"));

        try {
            ResponseEntity<UploadResponse> response = restTemplate.postForEntity(
                url,
                new HttpEntity<>(body),
                UploadResponse.class
            );

            if (response.getStatusCode().is2xxSuccessful()) {
                UploadResponse result = response.getBody();
                System.out.println("File URL: " + result.getFileUrl());
            }
        } catch (HttpClientErrorException e) {
            System.err.println("Upload failed: " + e.getStatusCode());
            System.err.println("Error details: " + e.getResponseBodyAsString());
        }
    }

    static class UploadResponse {
        private String fileUrl;
        // Getters and Setters
    }
}

5. 自定义请求头与认证

添加认证头(如 JWT)或自定义请求头。

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;

public class AuthHeaderExample {

    public void uploadWithAuth() {
        RestTemplate restTemplate = new RestTemplate();
        String url = "http://api.example.com/secure-upload";
        String token = "Bearer abc123";

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        headers.set("Authorization", token); // JWT 认证

        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        body.add("file", new FileSystemResource("secret-doc.pdf"));

        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
        String response = restTemplate.postForObject(url, requestEntity, String.class);
    }
}

关键注意事项

  1. Content-Type 自动处理
    RestTemplate 在发送 MultiValueMap 时会自动设置 Content-Typemultipart/form-data,无需手动指定。

  2. 资源释放
    使用 FileSystemResourceInputStreamResource 时,确保及时关闭文件流(推荐用 try-with-resources)。

  3. 文件名编码
    若文件名含特殊字符(如中文),需在客户端或服务端统一处理编码:

    String encodedFilename = URLEncoder.encode(rawFilename, StandardCharsets.UTF_8);
    
  4. 性能优化

    • 大文件上传时,使用分块或流式传输避免内存溢出。
    • 复用 RestTemplate 实例(通常配置为单例)。

❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值