Spring WebFlux: Serve files from controller

£可爱£侵袭症+ 提交于 2020-06-10 03:47:08

问题


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();
        }
    }
}

回答1:


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;
    }
}

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.

Now, with Spring WebFlux, you can also configure the same spring.resources.static-locations configuration property to serve static resources.

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));
    }
}

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.



来源:https://stackoverflow.com/questions/49259156/spring-webflux-serve-files-from-controller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!