我正在尝试以webflux方式上传一大堆文件。 我无法在服务器和客户端的内存中加载所有文件。 我宁愿不进行多次rest调用,因为我想保持数据传输的状态并在一个文件损坏的情况下将其取消,这就是为什么我要使用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);
}
}