Spring Boot 可以设置从控制器端点下载的文件的名称吗?
Can Spring Boot set the name of a file being downloaded from a controller endpoint?
Java 11 和 Spring 引导 2.5.x 在这里。我知道我可以设置一个控制器来 return 文件的内容,如下所示:
@GetMapping(
value = "/get-image-with-media-type",
produces = MediaType.IMAGE_JPEG_VALUE
)
public @ResponseBody byte[] getImageWithMediaType() throws IOException {
InputStream in = getClass()
.getResourceAsStream("/path/to/some/image.jpg");
return IOUtils.toByteArray(in);
}
但是如果我想控制传回文件的名称怎么办?例如,在服务器端,文件名可能存储为“image.jpg”,但我想将其 return 编辑为“[=12” =]",其中 <userId>
是发出请求的经过身份验证的用户的用户 ID,其中 <YYYY-mm-DD>
是发出请求的日期?
例如,如果用户 123 在 2021 年 12 月 10 日发出请求,则文件将下载为“123-2021-12-10-image.jpg”,如果用户 234 在 2022 年 1 月 17 日提出请求,它将被下载为“234-2022-01-17-image.jpg”。这可以控制 Spring/Java/server-side,还是由 HTTP 客户端(浏览器、PostMan 等)决定文件名?
请试试这个,在线评论:
package com.example;
import java.io.IOException;
import java.security.Principal;
import java.util.Date;
import org.apache.commons.io.IOUtils;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class SomeController {
@GetMapping(
value = "/get-image-with-media-type",
produces = MediaType.IMAGE_JPEG_VALUE
) // we can inject user like this (can be null, when not secured):
public ResponseEntity<byte[]> getImageWithMediaType(Principal user) throws IOException {
// XXXResource is the "spring way", FileSystem- alternatively: ClassPath-, ServletContext-, ...
FileSystemResource fsr = new FileSystemResource("/path/to/some/image.jpg");
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set(HttpHeaders.CONTENT_DISPOSITION,
// for direct downlad "inline", for "save as" dialog "attachment" (browser dependent)
// filename placeholders: %1$s: user id string, 2$tY: year 4 digits, 2$tm: month 2 digits, %2$td day of month 2 digits
String.format("inline; filename=\"%1$s-%2$tY-%2$tm-%2$td-image.jpg\"",
// user name, current (server) date:
user == null ? "anonymous" : user.getName(), new Date()));
// and fire:
return new ResponseEntity<>(
IOUtils.toByteArray(fsr.getInputStream()),
responseHeaders,
HttpStatus.OK
);
}
}
相关参考:
- Method Arguments(Principal)
- Formatter
- ResponseEntity(+ headers sample)
- RFC2616(第 19.5.1 节内容处置)
使用 ContentDisposition
它可以看起来(只是)像:
responseHeaders.setContentDisposition(
ContentDisposition
.inline()// or .attachment()
.filename(// format file name:
String.format(
"%1$s-%2$tY-%2$tm-%2$td-image.jpg",
user == null ? "anonymous" : user.getName(),
new Date()
)
)
.build()
);
TYVM:How to set 'Content-Disposition' and 'Filename' when using FileSystemResource to force a file download file?
Java 11 和 Spring 引导 2.5.x 在这里。我知道我可以设置一个控制器来 return 文件的内容,如下所示:
@GetMapping(
value = "/get-image-with-media-type",
produces = MediaType.IMAGE_JPEG_VALUE
)
public @ResponseBody byte[] getImageWithMediaType() throws IOException {
InputStream in = getClass()
.getResourceAsStream("/path/to/some/image.jpg");
return IOUtils.toByteArray(in);
}
但是如果我想控制传回文件的名称怎么办?例如,在服务器端,文件名可能存储为“image.jpg”,但我想将其 return 编辑为“[=12” =]",其中 <userId>
是发出请求的经过身份验证的用户的用户 ID,其中 <YYYY-mm-DD>
是发出请求的日期?
例如,如果用户 123 在 2021 年 12 月 10 日发出请求,则文件将下载为“123-2021-12-10-image.jpg”,如果用户 234 在 2022 年 1 月 17 日提出请求,它将被下载为“234-2022-01-17-image.jpg”。这可以控制 Spring/Java/server-side,还是由 HTTP 客户端(浏览器、PostMan 等)决定文件名?
请试试这个,在线评论:
package com.example;
import java.io.IOException;
import java.security.Principal;
import java.util.Date;
import org.apache.commons.io.IOUtils;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class SomeController {
@GetMapping(
value = "/get-image-with-media-type",
produces = MediaType.IMAGE_JPEG_VALUE
) // we can inject user like this (can be null, when not secured):
public ResponseEntity<byte[]> getImageWithMediaType(Principal user) throws IOException {
// XXXResource is the "spring way", FileSystem- alternatively: ClassPath-, ServletContext-, ...
FileSystemResource fsr = new FileSystemResource("/path/to/some/image.jpg");
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set(HttpHeaders.CONTENT_DISPOSITION,
// for direct downlad "inline", for "save as" dialog "attachment" (browser dependent)
// filename placeholders: %1$s: user id string, 2$tY: year 4 digits, 2$tm: month 2 digits, %2$td day of month 2 digits
String.format("inline; filename=\"%1$s-%2$tY-%2$tm-%2$td-image.jpg\"",
// user name, current (server) date:
user == null ? "anonymous" : user.getName(), new Date()));
// and fire:
return new ResponseEntity<>(
IOUtils.toByteArray(fsr.getInputStream()),
responseHeaders,
HttpStatus.OK
);
}
}
相关参考:
- Method Arguments(Principal)
- Formatter
- ResponseEntity(+ headers sample)
- RFC2616(第 19.5.1 节内容处置)
使用 ContentDisposition
它可以看起来(只是)像:
responseHeaders.setContentDisposition(
ContentDisposition
.inline()// or .attachment()
.filename(// format file name:
String.format(
"%1$s-%2$tY-%2$tm-%2$td-image.jpg",
user == null ? "anonymous" : user.getName(),
new Date()
)
)
.build()
);
TYVM:How to set 'Content-Disposition' and 'Filename' when using FileSystemResource to force a file download file?