private Flux<?> decodePartValues(Flux<Part> parts, MethodParameter elementType, BindingContext bindingContext, ServerWebExchange exchange, boolean isRequired) { return parts.flatMap(part -> { ServerHttpRequest partRequest = new PartServerHttpRequest(exchange.getRequest(), part); ServerWebExchange partExchange = exchange.mutate().request(partRequest).build(); if (logger.isDebugEnabled()) { logger.debug(exchange.getLogPrefix() + "Decoding part '" + part.name() + "'"); } return readBody(elementType, isRequired, bindingContext, partExchange); }); }
@Override public Flux<Part> read(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) { return Flux.create(new SynchronossPartGenerator(message, this.bufferFactory, this.streamStorageFactory)) .doOnNext(part -> { if (!Hints.isLoggingSuppressed(hints)) { LogFormatUtils.traceDebug(logger, traceOn -> Hints.getLogPrefix(hints) + "Parsed " + (isEnableLoggingRequestDetails() ? LogFormatUtils.formatValue(part, !traceOn) : "parts '" + part.name() + "' (content masked)")); } }); }
private void assertBarPart(Part part) { assertEquals("barPart", part.name()); assertTrue(part instanceof FormFieldPart); assertEquals("bar", ((FormFieldPart) part).value()); } }
@Override public Flux<Part> read(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) { return Flux.create(new SynchronossPartGenerator(message, this.bufferFactory, this.streamStorageFactory)) .doOnNext(part -> { if (!Hints.isLoggingSuppressed(hints)) { LogFormatUtils.traceDebug(logger, traceOn -> Hints.getLogPrefix(hints) + "Parsed " + (isEnableLoggingRequestDetails() ? LogFormatUtils.formatValue(part, !traceOn) : "parts '" + part.name() + "' (content masked)")); } }); }
@Test // SPR-16402 public void singleSubscriberWithResource() throws IOException { UnicastProcessor<Resource> processor = UnicastProcessor.create(); Resource logo = new ClassPathResource("/org/springframework/http/converter/logo.jpg"); Mono.just(logo).subscribe(processor); MultipartBodyBuilder bodyBuilder = new MultipartBodyBuilder(); bodyBuilder.asyncPart("logo", processor, Resource.class); Mono<MultiValueMap<String, HttpEntity<?>>> result = Mono.just(bodyBuilder.build()); Map<String, Object> hints = Collections.emptyMap(); this.writer.write(result, null, MediaType.MULTIPART_FORM_DATA, this.response, hints).block(); MultiValueMap<String, Part> requestParts = parse(hints); assertEquals(1, requestParts.size()); Part part = requestParts.getFirst("logo"); assertEquals("logo", part.name()); assertTrue(part instanceof FilePart); assertEquals("logo.jpg", ((FilePart) part).filename()); assertEquals(MediaType.IMAGE_JPEG, part.headers().getContentType()); assertEquals(logo.getFile().length(), part.headers().getContentLength()); }
@RequestMapping(value = "/post", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public Mono<Map<String, Object>> postFormData(@RequestBody Mono<MultiValueMap<String, Part>> parts) { // StringDecoder decoder = StringDecoder.allMimeTypes(true); return parts.flux().flatMap(map -> Flux.fromIterable(map.values())) .flatMap(Flux::fromIterable) .filter(part -> part instanceof FilePart) .reduce(new HashMap<String, Object>(), (files, part) -> { MediaType contentType = part.headers().getContentType(); long contentLength = part.headers().getContentLength(); files.put(part.name(), "data:"+contentType+";base64,"+contentLength); //TODO: get part data return files; }).map(files -> Collections.singletonMap("files", files)); }
private void assertFooPart(Part part) { assertEquals("fooPart", part.name()); assertTrue(part instanceof FilePart); assertEquals("foo.txt", ((FilePart) part).filename()); StepVerifier.create(DataBufferUtils.join(part.content())) .consumeNextWith(buffer -> { assertEquals(12, buffer.readableByteCount()); byte[] byteContent = new byte[12]; buffer.read(byteContent); assertEquals("Lorem Ipsum.", new String(byteContent)); }) .verifyComplete(); }
assertEquals("name 1", part.name()); assertEquals("value 1", ((FormFieldPart) part).value()); part = parts2.get(0); assertTrue(part instanceof FormFieldPart); assertEquals("name 2", part.name()); assertEquals("value 2+1", ((FormFieldPart) part).value()); part = parts2.get(1); assertTrue(part instanceof FormFieldPart); assertEquals("name 2", part.name()); assertEquals("value 2+2", ((FormFieldPart) part).value()); assertEquals("logo", part.name()); assertEquals("logo.jpg", ((FilePart) part).filename()); assertEquals(MediaType.IMAGE_JPEG, part.headers().getContentType()); assertEquals("utf8", part.name()); assertEquals("Hall\u00F6le.jpg", ((FilePart) part).filename()); assertEquals(MediaType.IMAGE_JPEG, part.headers().getContentType()); assertEquals("json", part.name()); assertEquals(MediaType.APPLICATION_JSON_UTF8, part.headers().getContentType()); assertEquals("publisher", part.name());
@Test public void resolveParts() { ServerHttpRequest request = generateMultipartRequest(); ResolvableType elementType = forClassWithGenerics(MultiValueMap.class, String.class, Part.class); MultiValueMap<String, Part> parts = this.reader.readMono(elementType, request, emptyMap()).block(); assertEquals(2, parts.size()); assertTrue(parts.containsKey("fooPart")); Part part = parts.getFirst("fooPart"); assertTrue(part instanceof FilePart); assertEquals("fooPart", part.name()); assertEquals("foo.txt", ((FilePart) part).filename()); DataBuffer buffer = DataBufferUtils.join(part.content()).block(); assertEquals(12, buffer.readableByteCount()); byte[] byteContent = new byte[12]; buffer.read(byteContent); assertEquals("Lorem Ipsum.", new String(byteContent)); assertTrue(parts.containsKey("barPart")); part = parts.getFirst("barPart"); assertTrue(part instanceof FormFieldPart); assertEquals("barPart", part.name()); assertEquals("bar", ((FormFieldPart) part).value()); }
assertEquals("text", part.name()); assertTrue(part instanceof FormFieldPart); FormFieldPart formFieldPart = (FormFieldPart) part; }) .consumeNextWith(part -> { assertEquals("file1", part.name()); assertTrue(part instanceof FilePart); FilePart filePart = (FilePart) part; }) .consumeNextWith(part -> { assertEquals("file2", part.name()); assertTrue(part instanceof FilePart); FilePart filePart = (FilePart) part;
private OperationRequestPart createOperationRequestPart(Part part) { ByteArrayOutputStream content = readPartBodyContent(part); return new OperationRequestPartFactory().create(part.name(), (part instanceof FilePart) ? ((FilePart) part).filename() : null, content.toByteArray(), part.headers()); }
@Override public Flux<Part> read(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) { return Flux.create(new SynchronossPartGenerator(message, this.bufferFactory, this.streamStorageFactory)) .doOnNext(part -> { if (!Hints.isLoggingSuppressed(hints)) { LogFormatUtils.traceDebug(logger, traceOn -> Hints.getLogPrefix(hints) + "Parsed " + (isEnableLoggingRequestDetails() ? LogFormatUtils.formatValue(part, !traceOn) : "parts '" + part.name() + "' (content masked)")); } }); }