来自.NET和Node我真的很难弄清楚如何将这个阻塞MVC控制器转移到非阻塞的WebFlux注释控制器?我已经理解了这些概念,但未能找到正确的异步Java IO方法(我期望返回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();
}
}
}
答案 0 :(得分:4)
首先,使用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 Boot,spring.resources.static-locations
可以帮助您自定义位置。
现在,使用Spring WebFlux,您还可以配置相同的spring.resources.static-locations
配置属性来提供静态资源。
WebFlux版本看起来完全一样。如果您需要执行一些涉及某些I / O的逻辑,您可以直接返回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,如果返回的Resource
实际上是磁盘上的文件,我们将使用zero-copy mechanism来提高效率。