SpringCloud gateway requestのbody検証または変更
6053 ワード
2019.11.05更新:
次のバージョンでは、次のフィルタが追加されました.
解決策:
ymlファイルでカスタムヘッダ除去リストを構成する
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
往々にしてビジネスでは、ゲートウェイでリクエストパラメータを変更する必要があります(body付きリクエストのみに注意してください).springcloud gatewayには
それを参考にブロックを実現しました
注意:アップロードファイルにも要求bodyがあり、特殊な処理が必要です.
主なコードは次のとおりです.
転載する場合は出典を明記してください.https://blog.csdn.net/shuoshuo132
次のバージョンでは、次のフィルタが追加されました.
org.springframework.cloud.gateway.filter.headers.RemoveHopByHopHeadersFilter
デフォルトでは、次のヘッダが除去されます(この方法の目的は不明です).- connection
- keep-alive
- te
- transfer-encoding
- trailer
- proxy-authorization
- proxy-authenticate
- x-application-context
- upgrade
これにより、getHeadersメソッドを書き換えるときに追加したtransfer-encodingヘッダが除去され、bodyが解析できなくなります.解決策:
ymlファイルでカスタムヘッダ除去リストを構成する
spring:
cloud:
filter:
remove-hop-by-hop:
headers:
- connection
- keep-alive
- te
- trailer
- proxy-authorization
- proxy-authenticate
- x-application-context
- upgrade
ソースコードにはリンクが表示され、動的ルーティング構成が実現されます.https://github.com/SingleTigger/SpringCloudGateway-Nacos-Demo-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
往々にしてビジネスでは、ゲートウェイでリクエストパラメータを変更する必要があります(body付きリクエストのみに注意してください).springcloud gatewayには
ModifyRequestBodyGatewayFilterFactory
のfilterは、その実装を見て、入力タイプと出力タイプを指定する必要があります.比較的限られています.それを参考にブロックを実現しました
注意:アップロードファイルにも要求bodyがあり、特殊な処理が必要です.
主なコードは次のとおりです.
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.cloud.gateway.support.BodyInserterContext;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.codec.HttpMessageReader;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserter;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.HandlerStrategies;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiFunction;
/**
* @author chenws
* @date 2019/12/12 09:33:53
*/
@Component
public class CModifyRequestBodyGatewayFilterFactory extends AbstractGatewayFilterFactory {
private final List> messageReaders;
public CModifyRequestBodyGatewayFilterFactory() {
this.messageReaders = HandlerStrategies.withDefaults().messageReaders();
}
@Override
@SuppressWarnings("unchecked")
public GatewayFilter apply(Object config) {
return (exchange, chain) -> {
ServerRequest serverRequest = ServerRequest.create(exchange,
this.messageReaders);
Mono modifiedBody = serverRequest.bodyToMono(String.class)
.flatMap(originalBody -> modifyBody()
.apply(exchange,Mono.just(originalBody)));
BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody,
String.class);
HttpHeaders headers = new HttpHeaders();
headers.putAll(exchange.getRequest().getHeaders());
headers.remove(HttpHeaders.CONTENT_LENGTH);
CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange,
headers);
return bodyInserter.insert(outputMessage, new BodyInserterContext())
.then(Mono.defer(() -> {
ServerHttpRequest decorator = decorate(exchange, headers,
outputMessage);
return chain.filter(exchange.mutate().request(decorator).build());
}));
};
}
/**
* body
* @return apply Mono, body
*/
private BiFunction,Mono> modifyBody(){
return (exchange,json)-> {
AtomicReference result = new AtomicReference<>();
json.subscribe(
value -> {
//value body,
result.set(value);
System.out.println(result.get());
},
Throwable::printStackTrace
);
return Mono.just(result.get());
};
}
private ServerHttpRequestDecorator decorate(ServerWebExchange exchange, HttpHeaders headers,
CachedBodyOutputMessage outputMessage) {
return new ServerHttpRequestDecorator(exchange.getRequest()) {
@Override
public HttpHeaders getHeaders() {
long contentLength = headers.getContentLength();
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.putAll(super.getHeaders());
if (contentLength > 0) {
httpHeaders.setContentLength(contentLength);
}
else {
httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
}
return httpHeaders;
}
@Override
public Flux getBody() {
return outputMessage.getBody();
}
};
}
}
転載する場合は出典を明記してください.https://blog.csdn.net/shuoshuo132