Spring Webflux загрузка нескольких файлов - PullRequest
0 голосов
/ 14 октября 2019

Я пытаюсь загрузить большой список файлов способом webflux. Я не могу загрузить все файлы в память на стороне сервера и клиента. Я скорее не делаю многократные вызовы покоя, потому что я хочу сохранить состояние передачи данных и отменить его, если один файл поврежден, поэтому я хочу использовать webflux (я могу ошибаться).

Я проверилмного вещей, но я не могу заставить клиента и сервер работать правильно (неверный тип контента, ошибка в теле синтаксического анализа и т. обработчик для сервера. Я думаю, что я близок, чтобы сделать это, но мне нужна ваша помощь! Можете ли вы помочь мне, пожалуйста? Большое спасибо!

Есть мой модульный тест:

@Slf4j
@ExtendWith(SpringExtension.class)
@WebFluxTest(FileApiRouter.class)
@Import({FileHandler.class, HttpConfiguration.class})
public class FileControllerTest {

    private static final String DICOM_FILE = "image-000001.dcm";

    @Autowired
    private WebTestClient webTestClient;

    @Autowired
    private HttpConfiguration configuration;

    @MockBean
    private FileService service;

    private void populateHeaders(HttpHeaders headers) {
        headers.set(configuration.getSerieHeader(), "{\"labels\":[\"label1\",\"label2\"]}");
    }

    private MultipartFile fileParts(int i) {
        return new MockMultipartFile("foo"+i, "foo"+i+".txt",
                MediaType.MULTIPART_FORM_DATA_VALUE, "File test content".getBytes());
    }

    @Test
    @DisplayName("[TU] Dicom Http upload filepart")
    public void uploadFile_When1File_Then1String() {

        doReturn(Mono.just("OK")).when(service).storeFilePart(any());

        var dicomFlux = Flux
                .range(0, 3)
                .map(this::fileParts)
                .delayElements(Duration.ofSeconds(1));

        webTestClient.post()
                .uri(FileApiRouter.RESOURCE)
                .headers(this::populateHeaders)
                .contentType(MediaType.MULTIPART_FORM_DATA)
                .body(BodyInserters.fromMultipartAsyncData("dicoms",dicomFlux, MultipartFile.class))
                .exchange()
                .expectStatus()
                .is2xxSuccessful()
                .expectBodyList(String.class)
                .contains("OK","OK","OK")
        ;

    }
}

Мой маршрутизатор и обработчик:

@Configuration
    public class FileApiRouter {

        public static final String BASE = "/api";
        public static final String V1 = BASE + "/v1";
        public static final String RESOURCE = V1 + "/files";

        private FileHandler  handler;

        public FileApiRouter(FileHandler handler) {
            this.handler = handler;
        }

       @Bean
    public RouterFunction<ServerResponse> postFile() {
        return route(POST(RESOURCE).and(contentType(MediaType.MULTIPART_FORM_DATA)), handler::handleFileParts);
    }


    }


    @Component
    @Slf4j
    public class FileHandler {

        private final FileService service;

        private final HttpConfiguration configuration;

        public FileHandler(FileService service, HttpConfiguration configuration) {
            this.service = service;
            this.configuration = configuration;
        }


        public Mono<ServerResponse> handleFileParts(ServerRequest request) {

        var meta = request.headers().header(configuration.getSerieHeader());
        var then = request
                .body(BodyExtractors.toParts())
                .filter(FilePart.class::isInstance)
                .cast(FilePart.class)
                .flatMap(service::storeFilePart);
        return ServerResponse.ok().body(then, String.class);
    }

    }
...