来自.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(); } } }
首先,使用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的静态资源支持。使用Spring Boot,spring.resources.static-locations可以帮助您自定义位置。
spring.resources.static-locations
现在,使用Spring WebFlux,您还可以配置相同的spring.resources.static-locations配置属性来提供静态资源。
它的WebFlux版本看起来完全一样。如果您需要执行涉及某些I / O的逻辑,则可以返回a Mono<Resource>而不是Resource直接返回a ,如下所示:
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的实际上是磁盘上的文件,我们将利用零复制机制,这将使事情更高效。