@Override public String toString() { return "Part '" + name() + "=" + this.content + "'"; } }
@Override public Flux<DataBuffer> getBody() { return this.part.content(); } }
@Override public String toString() { return "Part '" + name() + "', filename='" + this.filename + "'"; } }
@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()); }
@Override protected void extendTypedReaders(List<HttpMessageReader<?>> typedReaders) { if (synchronossMultipartPresent) { boolean enable = isEnableLoggingRequestDetails(); SynchronossPartHttpMessageReader partReader = new SynchronossPartHttpMessageReader(); partReader.setEnableLoggingRequestDetails(enable); typedReaders.add(partReader); MultipartHttpMessageReader reader = new MultipartHttpMessageReader(partReader); reader.setEnableLoggingRequestDetails(enable); typedReaders.add(reader); } }
@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 Part createPart(StreamStorage storage, HttpHeaders httpHeaders) { String filename = MultipartUtils.getFileName(httpHeaders); if (filename != null) { return new SynchronossFilePart(httpHeaders, filename, storage, this.bufferFactory); } else if (MultipartUtils.isFormField(httpHeaders, this.context)) { String value = MultipartUtils.readFormParameterValue(storage, httpHeaders); return new SynchronossFormFieldPart(httpHeaders, this.bufferFactory, value); } else { return new SynchronossPart(httpHeaders, storage, this.bufferFactory); } }
@Override public Flux<DataBuffer> content() { return DataBufferUtils.readInputStream(getStorage()::getInputStream, getBufferFactory(), 4096); }
@Test public void bodyError() { ServerHttpRequest request = generateErrorMultipartRequest(); ResolvableType elementType = forClassWithGenerics(MultiValueMap.class, String.class, Part.class); StepVerifier.create(this.reader.readMono(elementType, request, emptyMap())).verifyError(); }
/** * Convenience method to copy the content of the file in this part to the * given destination file. If the destination file already exists, it will * be truncated first. * <p>The default implementation delegates to {@link #transferTo(Path)}. * @param dest the target file * @return completion {@code Mono} with the result of the file transfer, * possibly {@link IllegalStateException} if the part isn't a file * @see #transferTo(Path) */ default Mono<Void> transferTo(File dest) { return transferTo(dest.toPath()); }
@Override public Flux<MultiValueMap<String, Part>> read(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) { return Flux.from(readMono(elementType, message, hints)); }
@Override public HttpHeaders getHeaders() { return this.part.headers(); }
/** * Constructor with explicit list of writers for serializing parts and a * writer for plain form data to fall back when no media type is specified * and the actual map consists of String values only. * @param partWriters the writers for serializing parts * @param formWriter the fallback writer for form data, {@code null} by default */ public MultipartHttpMessageWriter(List<HttpMessageWriter<?>> partWriters, @Nullable HttpMessageWriter<MultiValueMap<String, String>> formWriter) { this.partWriters = partWriters; this.formWriter = formWriter; this.supportedMediaTypes = initMediaTypes(formWriter); }
private Charset getCharset() { String name = MultipartUtils.getCharEncoding(headers()); return (name != null ? Charset.forName(name) : StandardCharsets.UTF_8); }
@Override public void onPartFinished(StreamStorage storage, Map<String, List<String>> headers) { HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.putAll(headers); this.sink.next(createPart(storage, httpHeaders)); }
private Part createPart(StreamStorage storage, HttpHeaders httpHeaders) { String filename = MultipartUtils.getFileName(httpHeaders); if (filename != null) { return new SynchronossFilePart(httpHeaders, filename, storage, this.bufferFactory); } else if (MultipartUtils.isFormField(httpHeaders, this.context)) { String value = MultipartUtils.readFormParameterValue(storage, httpHeaders); return new SynchronossFormFieldPart(httpHeaders, this.bufferFactory, value); } else { return new SynchronossPart(httpHeaders, storage, this.bufferFactory); } }
@Override public String toString() { return "Part '" + name() + "=" + this.content + "'"; } }
@Override public String toString() { return "Part '" + name() + "', filename='" + this.filename + "'"; } }