【问题标题】:Is possible to return a S3Object from Spring Boot Controller?是否可以从 Spring Boot Controller 返回 S3Object?
【发布时间】:2025-12-15 18:20:05
【问题描述】:

我对 REST API 和 Spring Boot 非常陌生。我正在编写一个微服务,它被要求提供 S3 文件,并且必须以某种方式返回它们。文件太大(2GB+)无法保存在微服务内存中,然后将其发送回调用者,所以我想我可以简单地返回一个序列化的 S3Object,我的客户可以通过重复调用来流式传输文件内容和块S3ObjectInputStream.read(bytes[]).

我很难让这成为可能,而且由于我的知识有限,我什至不知道这是否可能,或者我是否正在思考。

我已经尝试返回一个 ResponseEntity。使用 Postman 一切都很酷,并且 S3Object 可以使用 jackson 库正确序列化,但客户端的反序列化会崩溃,因为方法 S3Object.setObjectContent 过载并且多个 setter 冲突。

以 SerializationUtils.serialize(S3Object) 作为主体返回 ResponseEntity 也失败了。即使是 S3Object 实现了 Serializable 接口,每次得到的 byte[] 长度都是 1000,而当我反序列化时,我无法获取对象内容,因为 S3Object.getObjectContent() 总是返回 null。

我能做什么?

【问题讨论】:

  • 你不能创建一个签名的下载 url 并重定向到它吗?让用户直接从 S3 下载它而不是通过您的服务器?

标签: java spring spring-boot serialization amazon-s3


【解决方案1】:

不需要,我不认为。下面是一个如何使用 RESTful api 返回请求文件的示例:

@RequestMapping(
    value = "/downloads/{fileName}",
    method = {RequestMethod.GET, RequestMethod.OPTIONS},
    produces = {MediaType.APPLICATION_OCTET_STREAM_VALUE})
@ResponseStatus(value = HttpStatus.OK)
public void downloadPolicyDocument( 
    @PathVariable("fileName") String fileName, 
    HttpServletResponse response) throws IOException {

    response.setCharacterEncoding("UTF-8");
    response.addHeader("Access-Control-Allow-Headers", "Range");
    response.addHeader("Access-Control-Expose-Headers", "Accept-Ranges, Content-Encoding, Content-Length, Content-Range");
    response.setHeader("Content-Disposition", "attachment; filename=\"" + id + "\"");

    try (InputStream inputStream = yourMethodThatGetsTheFileAsBufferedInputStream(fileName)) {

        ReadableByteChannel inputChannel = Channels.newChannel(inputStream);
        WritableByteChannel outputChannel = Channels.newChannel(response.getOutputStream());
        response.setContentLength(fastChannelCopy(inputChannel, outputChannel));
    }
    catch (IOException e) {
        throw new YourCustom404Exception(e.getMessage(), e);
    }
}

将其他 MediaType 添加到您希望从此端点下载的“produces”属性,或为每个媒体类型添加另一个类似的端点。

【讨论】:

    最近更新 更多