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;
            }
        }
    }

 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐