Spring - Cloud - Gateway 가 multipart / form - data 를 가 져 올 때 정상적으로 가 져 올 수 없습니다.
package com.cango.center.gateway.filter;
import java.util.Collections;
import java.util.List;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.ResolvableType;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.codec.HttpMessageReader;
import org.springframework.http.codec.multipart.FormFieldPart;
import org.springframework.http.codec.multipart.Part;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.server.HandlerStrategies;
import org.springframework.web.server.ServerWebExchange;
import com.XX.center.gateway.entity.GatewayContext;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
* .
*
* @author zyb
*/
@Component
public class GatewayContextFilter extends BaseFilter {
/**
* default HttpMessageReader.
*/
private static final List> MESSAGE_READERS = HandlerStrategies.withDefaults().messageReaders();
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
final ServerHttpRequest request = exchange.getRequest();
final String path = request.getPath().pathWithinApplication().value();
final GatewayContext gatewayContext = new GatewayContext();
gatewayContext.setPath(path);
exchange.getAttributes().put(GatewayContext.CACHE_GATEWAY_CONTEXT, gatewayContext);
return DataBufferUtils.join(exchange.getRequest().getBody()).flatMap(dataBuffer -> {
DataBufferUtils.retain(dataBuffer);
final Flux cachedFlux = Flux.defer(() -> Flux.just(dataBuffer.slice(0, dataBuffer.readableByteCount())));
final ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(exchange.getRequest()) {
@Override
public Flux getBody() {
return cachedFlux;
}
};
final ServerWebExchange mutatedExchange = exchange.mutate().request(mutatedRequest).build();
return cacheBody(mutatedExchange, chain, gatewayContext);
});
}
@SuppressWarnings("unchecked")
private Mono cacheBody(ServerWebExchange exchange, GatewayFilterChain chain, GatewayContext gatewayContext) {
final HttpHeaders headers = exchange.getRequest().getHeaders();
if (headers.getContentLength() == 0) {
return chain.filter(exchange);
}
final ResolvableType resolvableType;
if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(headers.getContentType())) {
resolvableType = ResolvableType.forClassWithGenerics(MultiValueMap.class, String.class, Part.class);
} else {
resolvableType = ResolvableType.forClass(String.class);
}
return MESSAGE_READERS.stream().filter(reader -> reader.canRead(resolvableType, exchange.getRequest().getHeaders().getContentType())).findFirst()
.orElseThrow(() -> new IllegalStateException("no suitable HttpMessageReader.")).readMono(resolvableType, exchange.getRequest(), Collections.emptyMap()).flatMap(resolvedBody -> {
if (resolvedBody instanceof MultiValueMap) {
final Part partInfo = (Part) ((MultiValueMap) resolvedBody).getFirst("info");
if (partInfo instanceof FormFieldPart) {
gatewayContext.setRequestBody(((FormFieldPart) partInfo).value());
}
} else {
gatewayContext.setRequestBody((String) resolvedBody);
}
return chain.filter(exchange);
});
}
}
참고:https://github.com/xurui8691413/sping-cloud-gateway-read-multipart-filter/blob/master/spring-cloud-gateway-sample
도움 이 됐 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
thymeleaf로 HTML 페이지를 동적으로 만듭니다 (spring + gradle)지난번에는 에서 화면에 HTML을 표시했습니다. 이번에는 화면을 동적으로 움직여보고 싶기 때문에 입력한 문자를 화면에 표시시키고 싶습니다. 초보자의 비망록이므로 이상한 점 등 있으면 지적 받을 수 있으면 기쁩니다! ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.