我试图从Spring启动休息服务下载文件.
@RequestMapping(path="/downloadFile",method=RequestMethod.GET)
@Consumes(MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<InputStreamReader> downloadDocument(
String acquistionId,
String fileType,
Integer expressVfId) throws IOException {
File file2Upload = new File("C:\\Users\\admin\\Desktop\\bkp\\1.rtf");
HttpHeaders headers = new HttpHeaders();
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
headers.add("Pragma", "no-cache");
headers.add("Expires", "0");
InputStreamReader i = new InputStreamReader(new FileInputStream(file2Upload));
System.out.println("The length of the file is : "+file2Upload.length());
return ResponseEntity.ok().headers(headers).contentLength(file2Upload.length())
.contentType(MediaType.parseMediaType("application/octet-stream"))
.body(i);
}
Run Code Online (Sandbox Code Playgroud)
当我尝试从浏览器下载文件时,它会开始下载,但始终会失败.导致下载失败的服务有什么问题吗?
fat*_*ddy 109
选项1使用InputStreamResource
给定InputStream的资源实现.
只有在没有其他特定资源实现适用时才应使用.特别是,在可能的情况下,更喜欢ByteArrayResource或任何基于文件的资源实现.
@RequestMapping(path = "/download", method = RequestMethod.GET)
public ResponseEntity<Resource> download(String param) throws IOException {
// ...
InputStreamResource resource = new InputStreamResource(new FileInputStream(file));
return ResponseEntity.ok()
.headers(headers)
.contentLength(file.length())
.contentType(MediaType.parseMediaType("application/octet-stream"))
.body(resource);
}
Run Code Online (Sandbox Code Playgroud)
Option2作为InputStreamResource的文档建议 - 使用ByteArrayResource:
@RequestMapping(path = "/download", method = RequestMethod.GET)
public ResponseEntity<Resource> download(String param) throws IOException {
// ...
Path path = Paths.get(file.getAbsolutePath());
ByteArrayResource resource = new ByteArrayResource(Files.readAllBytes(path));
return ResponseEntity.ok()
.headers(headers)
.contentLength(file.length())
.contentType(MediaType.parseMediaType("application/octet-stream"))
.body(resource);
}
Run Code Online (Sandbox Code Playgroud)
Fel*_*ati 15
我建议使用StreamingResponseBody,因为有了它,应用程序可以直接写入响应 (OutputStream),而无需阻止 Servlet 容器线程。如果您正在下载一个非常大的文件,这是一个很好的方法。
@GetMapping("download")
public StreamingResponseBody downloadFile(HttpServletResponse response, @PathVariable Long fileId) {
FileInfo fileInfo = fileService.findFileInfo(fileId);
response.setContentType(fileInfo.getContentType());
response.setHeader(
HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=\"" + fileInfo.getFilename() + "\"");
return outputStream -> {
int bytesRead;
byte[] buffer = new byte[BUFFER_SIZE];
InputStream inputStream = fileInfo.getInputStream();
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
};
}
Run Code Online (Sandbox Code Playgroud)
Ps.: 使用StreamingResponseBody 时,强烈建议配置 Spring MVC 中使用的 TaskExecutor 来执行异步请求。TaskExecutor 是一个接口,它抽象了一个 Runnable 的执行。
更多信息:https : //medium.com/swlh/streaming-data-with-spring-boot-restful-web-service-87522511c071
下面的示例代码对我有用,可能会对某人有所帮助。
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@RestController
@RequestMapping("/app")
public class ImageResource {
private static final String EXTENSION = ".jpg";
private static final String SERVER_LOCATION = "/server/images";
@RequestMapping(path = "/download", method = RequestMethod.GET)
public ResponseEntity<Resource> download(@RequestParam("image") String image) throws IOException {
File file = new File(SERVER_LOCATION + File.separator + image + EXTENSION);
HttpHeaders header = new HttpHeaders();
header.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=img.jpg");
header.add("Cache-Control", "no-cache, no-store, must-revalidate");
header.add("Pragma", "no-cache");
header.add("Expires", "0");
Path path = Paths.get(file.getAbsolutePath());
ByteArrayResource resource = new ByteArrayResource(Files.readAllBytes(path));
return ResponseEntity.ok()
.headers(header)
.contentLength(file.length())
.contentType(MediaType.parseMediaType("application/octet-stream"))
.body(resource);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 8
我想分享一种使用 JavaScript (ES6)、React和Spring Boot后端下载文件的简单方法:
- Spring Boot Rest 控制器
来自org.springframework.core.io.Resource 的资源
@SneakyThrows
@GetMapping("/files/{filename:.+}/{extraVariable}")
@ResponseBody
public ResponseEntity<Resource> serveFile(@PathVariable String filename, @PathVariable String extraVariable) {
Resource file = storageService.loadAsResource(filename, extraVariable);
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getFilename() + "\"")
.body(file);
}
Run Code Online (Sandbox Code Playgroud)
- React,使用AXIOS 的API 调用
将 responseType 设置为arraybuffer以指定响应中包含的数据类型。
export const DownloadFile = (filename, extraVariable) => {
let url = 'http://localhost:8080/files/' + filename + '/' + extraVariable;
return axios.get(url, { responseType: 'arraybuffer' }).then((response) => {
return response;
})};
Run Code Online (Sandbox Code Playgroud)
最后一步>下载
的帮助下 JS文件下载 ,你可以触发浏览器,如果它被下载到数据保存到文件中。
DownloadFile('filename.extension', 'extraVariable').then(
(response) => {
fileDownload(response.data, filename);
}
, (error) => {
// ERROR
});
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
106518 次 |
最近记录: |