Spring WebFlux:从控制器提供文件
Spring WebFlux: Serve files from controller
来自 .NET 和 Node 我真的很难弄清楚如何将这个阻塞的 MVC 控制器转移到一个非阻塞的 WebFlux 注释控制器?我已经理解了这些概念,但是找不到合适的异步 Java IO 方法(我希望 return Flux 或 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 实现的方法应该更像这样:
@RestController
@RequestMapping("/files")
public class FileController {
@GetMapping("/{fileName}")
public Resource getFile(@PathVariable String fileName) {
Resource resource = new FileSystemResource(fileName);
return resource;
}
}
另外,如果您 只是 服务这些资源而不需要额外的逻辑,您可以使用 Spring MVC 的 static resource support。使用 Spring 引导,spring.resources.static-locations
可以帮助您自定义位置。
现在,使用 Spring WebFlux,您还可以配置相同的 spring.resources.static-locations
配置 属性 来提供静态资源。
WebFlux 版本看起来完全一样。如果你需要执行一些涉及一些I/O的逻辑,你可以直接return一个Mono<Resource>
而不是一个Resource
,像这样:
@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,如果 returned Resource
实际上是磁盘上的一个文件,我们将利用 zero-copy mechanism 来提高效率。
来自 .NET 和 Node 我真的很难弄清楚如何将这个阻塞的 MVC 控制器转移到一个非阻塞的 WebFlux 注释控制器?我已经理解了这些概念,但是找不到合适的异步 Java IO 方法(我希望 return Flux 或 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 实现的方法应该更像这样:
@RestController
@RequestMapping("/files")
public class FileController {
@GetMapping("/{fileName}")
public Resource getFile(@PathVariable String fileName) {
Resource resource = new FileSystemResource(fileName);
return resource;
}
}
另外,如果您 只是 服务这些资源而不需要额外的逻辑,您可以使用 Spring MVC 的 static resource support。使用 Spring 引导,spring.resources.static-locations
可以帮助您自定义位置。
现在,使用 Spring WebFlux,您还可以配置相同的 spring.resources.static-locations
配置 属性 来提供静态资源。
WebFlux 版本看起来完全一样。如果你需要执行一些涉及一些I/O的逻辑,你可以直接return一个Mono<Resource>
而不是一个Resource
,像这样:
@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,如果 returned Resource
实际上是磁盘上的一个文件,我们将利用 zero-copy mechanism 来提高效率。