Spring WebFlux:从控制器提供文件 [英] Spring WebFlux: Serve files from controller
问题描述
来自.NET和Node,我真的很难弄清楚如何将该阻塞的MVC控制器转移到非阻塞的WebFlux注释的控制器?我已经理解了这些概念,但是没有找到合适的异步Java IO方法(我希望该方法可以返回Flux或Mono).
Coming from .NET and Node I really have a hard time to figure out how to transfer this blocking MVC controller to a non-blocking WebFlux annotated controller? I've understood the concepts, but fail to find the proper async Java IO method (which I would expect to return a Flux or Mono).
@RestController
@RequestMapping("/files")
public class FileController {
@GetMapping("/{fileName}")
public void getFile(@PathVariable String fileName, HttpServletResponse response) {
try {
File file = new File(fileName);
InputStream in = new java.io.FileInputStream(file);
FileCopyUtils.copy(in, response.getOutputStream());
response.flushBuffer();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
推荐答案
首先,使用Spring MVC实现该目标的方法应如下所示:
First, the way to achieve that with Spring MVC should look more like this:
@RestController
@RequestMapping("/files")
public class FileController {
@GetMapping("/{fileName}")
public Resource getFile(@PathVariable String fileName) {
Resource resource = new FileSystemResource(fileName);
return resource;
}
}
此外,如果您只是在没有附加逻辑的情况下仅服务器这些资源,则可以使用Spring MVC的
Also, not that if you just server those resources without additional logic, you can use Spring MVC's static resource support. With Spring Boot, spring.resources.static-locations
can help you customize the locations.
现在,使用Spring WebFlux,您还可以配置相同的spring.resources.static-locations
配置属性以提供静态资源.
Now, with Spring WebFlux, you can also configure the same spring.resources.static-locations
configuration property to serve static resources.
该WebFlux版本看起来完全一样.如果需要执行涉及某些I/O的逻辑,则可以直接返回Mono<Resource>
而不是Resource
,例如:
The WebFlux version of that looks exactly the same. If you need to perform some logic involving some I/O, you can return a Mono<Resource>
instead of a Resource
directly, like this:
@RestController
@RequestMapping("/files")
public class FileController {
@GetMapping("/{fileName}")
public Mono<Resource> getFile(@PathVariable String fileName) {
return fileRepository.findByName(fileName)
.map(name -> new FileSystemResource(name));
}
}
请注意,对于WebFlux,如果返回的Resource
实际上是磁盘上的文件,我们将使用
Note that with WebFlux, if the returned Resource
is actually a file on disk, we will leverage a zero-copy mechanism that will make things more efficient.
这篇关于Spring WebFlux:从控制器提供文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!