ModifyRequestBodyGatewayFilterFactory获取并修改请求体

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

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Spring Cloud Gateway修改请求参数,可以使用Spring Cloud Gateway提供的一些过滤器来实现。具步骤如下: 1. 创建一个过滤器类,继承AbstractGatewayFilterFactory类,实现filter方法,该方法用于修改请求参数。例如: ``` public class ModifyRequestBodyGatewayFilterFactory extends AbstractGatewayFilterFactory<ModifyRequestBodyGatewayFilterFactory.Config> { public ModifyRequestBodyGatewayFilterFactory() { super(Config.class); } @Override public GatewayFilter apply(Config config) { return (exchange, chain) -> { // 获取请求参数 ServerHttpRequest request = exchange.getRequest(); Flux<DataBuffer> body = request.getBody(); MediaType contentType = request.getHeaders().getContentType(); Charset charset = contentType.getCharset() != null ? contentType.getCharset() : StandardCharsets.UTF_8; // 修改请求参数 String bodyStr = body.map(dataBuffer -> { byte[] bytes = new byte[dataBuffer.readableByteCount()]; dataBuffer.read(bytes); DataBufferUtils.release(dataBuffer); return new String(bytes, charset); }).reduce((s1, s2) -> s1 + s2).orElse(""); String modifiedBodyStr = modify(bodyStr); // 构造新的请求参数 byte[] newBodyBytes = modifiedBodyStr.getBytes(charset); DataBuffer newBodyBuffer = request.bufferFactory().wrap(newBodyBytes); // 构造新的请求对象 ServerHttpRequest newRequest = request.mutate().body(Mono.just(newBodyBuffer)).build(); // 继续执行后续过滤器链 return chain.filter(exchange.mutate().request(newRequest).build()); }; } private String modify(String body) { // 在此处实现修改请求参数的逻辑 return body; } public static class Config { // 配置参数 } } ``` 2. 在配置文件中配置过滤器,例如: ``` spring: cloud: gateway: routes: - id: modify_request_body_route uri: http://localhost:8080 predicates: - Path=/modifyRequestBody filters: - ModifyRequestBody=modifyRequestBodyFilter default-filters: - ModifyRequestBody=defaultModifyRequestBodyFilter ``` 其中,ModifyRequestBody为过滤器类的名称,modifyRequestBodyFilter和defaultModifyRequestBodyFilter为过滤器实例的名称,可以根据实际需求进行修改。 3. 在控制器中接收修改后的请求参数,例如: ``` @PostMapping("/modifyRequestBody") public String modifyRequestBody(@RequestBody String requestBody) { // 处理请求参数 return "success"; } ``` 在上述代码中,@RequestBody注解用于接收请求参数。如果请求参数已经被修改,那么控制器中接收到的参数就是修改后的参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值