Skip to content

Instantly share code, notes, and snippets.

@Gsealy
Last active December 11, 2019 08:54
Show Gist options
  • Save Gsealy/1450a0df67a80d56b6b430627af5a4ac to your computer and use it in GitHub Desktop.
Save Gsealy/1450a0df67a80d56b6b430627af5a4ac to your computer and use it in GitHub Desktop.
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.codec.ByteBufferDecoder;
import org.springframework.core.codec.StringDecoder;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.codec.DecoderHttpMessageReader;
import org.springframework.http.codec.FormHttpMessageReader;
import org.springframework.http.codec.HttpMessageReader;
import org.springframework.http.codec.json.Jackson2JsonDecoder;
import org.springframework.http.codec.multipart.MultipartHttpMessageReader;
import org.springframework.http.codec.multipart.Part;
import org.springframework.http.codec.multipart.SynchronossPartHttpMessageReader;
import org.springframework.http.codec.xml.Jaxb2XmlDecoder;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.BodyExtractor;
import org.springframework.web.reactive.function.BodyExtractors;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@Component
public class GetDataGatewayFilter implements GlobalFilter, Ordered {
static {
createContext();
}
private static final String CACHE_REQUEST_BODY_OBJECT_KEY = "cachedRequestBodyObject";
private static BodyExtractor.Context context;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
Flux<DataBuffer> body = exchange.getAttribute(CACHE_REQUEST_BODY_OBJECT_KEY);
ServerHttpRequest request = new ServerHttpRequestDecorator(exchange.getRequest()) {
@Override
public Flux<DataBuffer> getBody() {
return body;
}
};
Mono<MultiValueMap<String, String>> result = BodyExtractors.toFormData()
.extract(request, this.context);
MultiValueMap<String, String> formdata = FormDataToMap(result);
formdata.forEach((key, value) -> {
System.out.println(key + ":" + value.get(0));
});
return chain.filter(exchange);
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE + 10000;
}
public InputStream MultipartToInputStream(Mono<MultiValueMap<String, Part>> multipart) {
AtomicReference<InputStream> bodyRef = new AtomicReference<>();
multipart.log().subscribe(parts -> {
if (parts.size() < 1) {
return;
}
Map<String, Part> map = parts.toSingleValueMap();
Part filePart = map.get("files");
DataBufferUtils.join(filePart.content()).flatMap(buffer -> {
DataBufferUtils.retain(buffer);
Flux<DataBuffer> cachedFlux = Flux
.defer(() -> Flux.just(buffer.slice(0, buffer.readableByteCount())));
cachedFlux.subscribe(dataBuffer -> {
bodyRef.set(dataBuffer.asInputStream()
);
});
return null;
});
});
return bodyRef.get();
}
public MultiValueMap<String, String> FormDataToMap(Mono<MultiValueMap<String, String>> formdata) {
AtomicReference<MultiValueMap<String, String>> QueryRef = new AtomicReference<>();
formdata.subscribe(maps -> {
QueryRef.set(maps);
});
LinkedMultiValueMap<String, String> newList = new LinkedMultiValueMap<>(QueryRef.get());
return newList;
}
public static 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());
context = new BodyExtractor.Context() {
@Override
public List<HttpMessageReader<?>> messageReaders() {
return messageReaders;
}
@Override
public Optional<ServerHttpResponse> serverResponse() {
return Optional.empty();
}
@Override
public Map<String, Object> hints() {
return new HashMap<String, Object>();
}
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment