web-dev-qa-db-ja.com

Spring WebFlux:コントローラーからファイルを提供

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

まず、Spring MVCでそれを実現する方法は、次のようになります。

@RestController
@RequestMapping("/files")
public class FileController {

    @GetMapping("/{fileName}")
    public Resource getFile(@PathVariable String fileName) {
        Resource resource = new FileSystemResource(fileName);        
        return resource;
    }
}

また、追加のロジックなしでこれらのリソースをjustサーバーする場合は、Spring MVCの 静的リソースサポート を使用できます。 Spring Bootを使用すると、spring.resources.static-locationsを使用して場所をカスタマイズできます。

現在、Spring WebFluxを使用すると、静的リソースを提供するために同じspring.resources.static-locations構成プロパティを構成することもできます。

そのWebFluxバージョンはまったく同じに見えます。 I/Oを含むロジックを実行する必要がある場合は、次のように、Resourceの代わりにMono<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が実際にディスク上のファイルである場合、より効率的になる ゼロコピーメカニズム を利用することに注意してください。

5
Brian Clozel