ModifyRequestBodyGatewayFilterFactory获取并修改请求体
spring cloud gateway在GatewayFilter中获取并修改请求参数参考:https://blog.csdn.net/tianyaleixiaowu/article/details/83375246网上查询很多资料,但是都存在一些问题。后来仔细查看官方spring cloud gateway官方文档,发现它有提供相应拦截器官网api:https://cloud.spring.i
·
spring cloud gateway在GatewayFilter中获取并修改请求参数
参考:https://blog.csdn.net/tianyaleixiaowu/article/details/83375246
网上查询很多资料,但是都存在一些问题。后来仔细查看官方spring cloud gateway官方文档,发现它有提供相应拦截器
官网api:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.1.0.RC3/multi/multi_spring-cloud-gateway.html
果断查看源码找到相关的拦截器,分别如下,参考源码就能解决问题
1、涉及到的源码拦截器
AddRequestParameterGatewayFilterFactory.java
/*
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.cloud.gateway.filter.factory;
import java.net.URI;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.StringUtils;
import org.springframework.web.util.UriComponentsBuilder;
/**
* @author Spencer Gibb
*/
public class AddRequestParameterGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {
@Override
public GatewayFilter apply(NameValueConfig config) {
return (exchange, chain) -> {
URI uri = exchange.getRequest().getURI();
StringBuilder query = new StringBuilder();
String originalQuery = uri.getRawQuery();
if (StringUtils.hasText(originalQuery)) {
query.append(originalQuery);
if (originalQuery.charAt(originalQuery.length() - 1) != '&') {
query.append('&');
}
}
//TODO urlencode?
query.append(config.getName());
query.append('=');
query.append(config.getValue());
try {
URI newUri = UriComponentsBuilder.fromUri(uri)
.replaceQuery(query.toString())
.build(true)
.toUri();
ServerHttpRequest request = exchange.getRequest().mutate().uri(newUri).build();
return chain.filter(exchange.mutate().request(request).build());
} catch (RuntimeException ex) {
throw new IllegalStateException("Invalid URI query: \"" + query.toString() + "\"");
}
};
}
}
ModifyRequestBodyGatewayFilterFactory.java
/*
* Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.cloud.gateway.filter.factory.rewrite;
import java.util.Map;
import org.springframework.cloud.gateway.support.BodyInserterContext;
import org.springframework.cloud.gateway.support.CachedBodyOutputMessage;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.cloud.gateway.support.DefaultServerRequest;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.web.reactive.function.BodyInserter;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerRequest;
/**
* This filter is BETA and may be subject to change in a future release.
*/
public class ModifyRequestBodyGatewayFilterFactory
extends AbstractGatewayFilterFactory<ModifyRequestBodyGatewayFilterFactory.Config> {
public ModifyRequestBodyGatewayFilterFactory() {
super(Config.class);
}
@Deprecated
public ModifyRequestBodyGatewayFilterFactory(ServerCodecConfigurer codecConfigurer) {
this();
}
@Override
@SuppressWarnings("unchecked")
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
Class inClass = config.getInClass();
ServerRequest serverRequest = new DefaultServerRequest(exchange);
//TODO: flux or mono
Mono<?> modifiedBody = serverRequest.bodyToMono(inClass)
// .log("modify_request_mono", Level.INFO)
.flatMap(o -> config.rewriteFunction.apply(exchange, o));
BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, config.getOutClass());
HttpHeaders headers = new HttpHeaders();
headers.putAll(exchange.getRequest().getHeaders());
// the new content type will be computed by bodyInserter
// and then set in the request decorator
headers.remove(HttpHeaders.CONTENT_LENGTH);
// if the body is changing content types, set it here, to the bodyInserter will know about it
if (config.getContentType() != null) {
headers.set(HttpHeaders.CONTENT_TYPE, config.getContentType());
}
CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers);
return bodyInserter.insert(outputMessage, new BodyInserterContext())
// .log("modify_request", Level.INFO)
.then(Mono.defer(() -> {
ServerHttpRequestDecorator decorator = 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 {
// TODO: this causes a 'HTTP/1.1 411 Length Required' on httpbin.org
httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
}
return httpHeaders;
}
@Override
public Flux<DataBuffer> getBody() {
return outputMessage.getBody();
}
};
return chain.filter(exchange.mutate().request(decorator).build());
}));
};
}
public static class Config {
private Class inClass;
private Class outClass;
private String contentType;
@Deprecated
private Map<String, Object> inHints;
@Deprecated
private Map<String, Object> outHints;
private RewriteFunction rewriteFunction;
public Class getInClass() {
return inClass;
}
public Config setInClass(Class inClass) {
this.inClass = inClass;
return this;
}
public Class getOutClass() {
return outClass;
}
public Config setOutClass(Class outClass) {
this.outClass = outClass;
return this;
}
@Deprecated
public Map<String, Object> getInHints() {
return inHints;
}
@Deprecated
public Config setInHints(Map<String, Object> inHints) {
this.inHints = inHints;
return this;
}
@Deprecated
public Map<String, Object> getOutHints() {
return outHints;
}
@Deprecated
public Config setOutHints(Map<String, Object> outHints) {
this.outHints = outHints;
return this;
}
public RewriteFunction getRewriteFunction() {
return rewriteFunction;
}
public <T, R> Config setRewriteFunction(Class<T> inClass, Class<R> outClass,
RewriteFunction<T, R> rewriteFunction) {
setInClass(inClass);
setOutClass(outClass);
setRewriteFunction(rewriteFunction);
return this;
}
public Config setRewriteFunction(RewriteFunction rewriteFunction) {
this.rewriteFunction = rewriteFunction;
return this;
}
public String getContentType() {
return contentType;
}
public Config setContentType(String contentType) {
this.contentType = contentType;
return this;
}
}
}
更多推荐
已为社区贡献16条内容
所有评论(0)