@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<MultiValueMap<String, Part>> read(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) { return Flux.from(readMono(elementType, message, hints)); }
@Override public Mono<MultiValueMap<String, Part>> readMono(ResolvableType elementType, ReactiveHttpInputMessage inputMessage, Map<String, Object> hints) { Map<String, Object> allHints = Hints.merge(hints, Hints.SUPPRESS_LOGGING_HINT, true); return this.partReader.read(elementType, inputMessage, allHints) .collectMultimap(Part::name) .doOnNext(map -> { LogFormatUtils.traceDebug(logger, traceOn -> Hints.getLogPrefix(hints) + "Parsed " + (isEnableLoggingRequestDetails() ? LogFormatUtils.formatValue(map, !traceOn) : "parts " + map.keySet() + " (content masked)")); }) .map(this::toMultiValueMap); }
private MultiValueMap<String, Part> parse(Map<String, Object> hints) { MediaType contentType = this.response.getHeaders().getContentType(); assertNotNull("No boundary found", contentType.getParameter("boundary")); // see if Synchronoss NIO Multipart can read what we wrote SynchronossPartHttpMessageReader synchronossReader = new SynchronossPartHttpMessageReader(); MultipartHttpMessageReader reader = new MultipartHttpMessageReader(synchronossReader); MockServerHttpRequest request = MockServerHttpRequest.post("/") .contentType(MediaType.parseMediaType(contentType.toString())) .body(this.response.getBody()); ResolvableType elementType = ResolvableType.forClassWithGenerics( MultiValueMap.class, String.class, Part.class); MultiValueMap<String, Part> result = reader.readMono(elementType, request, hints) .block(Duration.ofSeconds(5)); assertNotNull(result); return result; }
@Before public void createContext() { final List<HttpMessageReader<?>> messageReaders = new ArrayList<>(); messageReaders.add(new DecoderHttpMessageReader<>(new ByteBufferDecoder())); messageReaders.add(new DecoderHttpMessageReader<>(StringDecoder.allMimeTypes())); messageReaders.add(new DecoderHttpMessageReader<>(new Jaxb2XmlDecoder())); messageReaders.add(new DecoderHttpMessageReader<>(new Jackson2JsonDecoder())); messageReaders.add(new FormHttpMessageReader()); SynchronossPartHttpMessageReader partReader = new SynchronossPartHttpMessageReader(); messageReaders.add(partReader); messageReaders.add(new MultipartHttpMessageReader(partReader)); messageReaders.add(new FormHttpMessageReader()); this.context = new BodyExtractor.Context() { @Override public List<HttpMessageReader<?>> messageReaders() { return messageReaders; } @Override public Optional<ServerHttpResponse> serverResponse() { return serverResponse; } @Override public Map<String, Object> hints() { return hints; } }; this.hints = new HashMap<String, Object>(); }
private LinkedMultiValueMap<String, Part> toMultiValueMap(Map<String, Collection<Part>> map) { return new LinkedMultiValueMap<>(map.entrySet().stream() .collect(Collectors.toMap(Map.Entry::getKey, e -> toList(e.getValue())))); }
private List<OperationRequestPart> extractRequestParts(ExchangeResult result) { if (!ClassUtils.isPresent( "org.synchronoss.cloud.nio.multipart.NioMultipartParserListener", getClass().getClassLoader())) { return Collections.emptyList(); } return new MultipartHttpMessageReader(new SynchronossPartHttpMessageReader()) .readMono(ResolvableType.forClass(Part.class), new ExchangeResultReactiveHttpInputMessage(result), Collections.emptyMap()) .onErrorReturn(new LinkedMultiValueMap<>()).block().values().stream() .flatMap((parts) -> parts.stream().map(this::createOperationRequestPart)) .collect(Collectors.toList()); }
@Override protected void extendTypedReaders(List<HttpMessageReader<?>> typedReaders) { if (synchronossMultipartPresent) { SynchronossPartHttpMessageReader partReader = new SynchronossPartHttpMessageReader(); typedReaders.add(partReader); typedReaders.add(new MultipartHttpMessageReader(partReader)); } }
private LinkedMultiValueMap<String, Part> toMultiValueMap(Map<String, Collection<Part>> map) { return new LinkedMultiValueMap<>(map.entrySet().stream() .collect(Collectors.toMap(Map.Entry::getKey, e -> toList(e.getValue())))); }
@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<MultiValueMap<String, Part>> read(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints) { return Flux.from(readMono(elementType, message, hints)); }
@Override protected void register(GenericApplicationContext context, CodecConfigurer configurer) { configurer.customCodecs().writer(new MultipartHttpMessageWriter()); if (!isClientCodec) { configurer.customCodecs().reader(new MultipartHttpMessageReader(new SynchronossPartHttpMessageReader())); } } }
private LinkedMultiValueMap<String, Part> toMultiValueMap(Map<String, Collection<Part>> map) { return new LinkedMultiValueMap<>(map.entrySet().stream() .collect(Collectors.toMap(Map.Entry::getKey, e -> toList(e.getValue())))); }
@Override public Mono<MultiValueMap<String, Part>> readMono(ResolvableType elementType, ReactiveHttpInputMessage inputMessage, Map<String, Object> hints) { Map<String, Object> allHints = Hints.merge(hints, Hints.SUPPRESS_LOGGING_HINT, true); return this.partReader.read(elementType, inputMessage, allHints) .collectMultimap(Part::name) .doOnNext(map -> { LogFormatUtils.traceDebug(logger, traceOn -> Hints.getLogPrefix(hints) + "Parsed " + (isEnableLoggingRequestDetails() ? LogFormatUtils.formatValue(map, !traceOn) : "parts " + map.keySet() + " (content masked)")); }) .map(this::toMultiValueMap); }
@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); } }
@Test // SPR-16545 public void transferTo() { ServerHttpRequest request = generateMultipartRequest(); ResolvableType elementType = forClassWithGenerics(MultiValueMap.class, String.class, Part.class); MultiValueMap<String, Part> parts = this.reader.readMono(elementType, request, emptyMap()).block(); assertNotNull(parts); FilePart part = (FilePart) parts.getFirst("fooPart"); assertNotNull(part); File dest = new File(System.getProperty("java.io.tmpdir") + "/" + part.filename()); part.transferTo(dest).block(Duration.ofSeconds(5)); assertTrue(dest.exists()); assertEquals(12, dest.length()); assertTrue(dest.delete()); }
private LinkedMultiValueMap<String, Part> toMultiValueMap(Map<String, Collection<Part>> map) { return new LinkedMultiValueMap<>(map.entrySet().stream() .collect(Collectors.toMap(Map.Entry::getKey, e -> toList(e.getValue())))); }
@Override public Mono<MultiValueMap<String, Part>> readMono(ResolvableType elementType, ReactiveHttpInputMessage inputMessage, Map<String, Object> hints) { Map<String, Object> allHints = Hints.merge(hints, Hints.SUPPRESS_LOGGING_HINT, true); return this.partReader.read(elementType, inputMessage, allHints) .collectMultimap(Part::name) .doOnNext(map -> { LogFormatUtils.traceDebug(logger, traceOn -> Hints.getLogPrefix(hints) + "Parsed " + (isEnableLoggingRequestDetails() ? LogFormatUtils.formatValue(map, !traceOn) : "parts " + map.keySet() + " (content masked)")); }) .map(this::toMultiValueMap); }
@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(); }
@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()); }