背景介绍

有个业务需求,要提供一套API接口给第三方调用。

在处理具体业务接口之前,设计上要先做个简单的鉴权,协商拟定了身份传参后,考虑到项目上已经用到了Spring Cloud Gateway ,就统一在网关模块做身份校验。

所以在服务端获取到请求的时候,要先拦截获取到请求传参,才能做后续的鉴权逻辑。

这里就需要解决一个问题:Spring Cloud Gateway 怎么读取请求传参?

搜索关键词:spring cloud gateway get request body

问题描述

问题:Spring Cloud Gateway 读取请求传参

这里只简单处理两种情况,get请求和post请求。

如果发现是get请求,就取url上的参数; 如果发现是post请求,就读取body的内容。

解决方案

参考 https://github.com/spring-cloud/spring-cloud-gateway/issues/747

定义了两个过滤器 filter,第一个过滤器ApiRequestFilter获取参数,放到上下文 GatewayContext。

注意如果是POST请求,请求体读取完后,要重新构造,填回请求体中。

第二个过滤器ApiVerifyFilter, 从上下文可以直接获取到参数。

后面如果其他业务也有读取参数的需求,就直接从上下文获取,不用再重复写获取参数的逻辑。

实现代码

GatewayContext

@Data

public class GatewayContext {

public static final String CACHE_GATEWAY_CONTEXT = "cacheGatewayContext";

/**

* cache json body

*/

private String cacheBody;

/**

* cache form data

*/

private MultiValueMap formData;

/**

* cache request path

*/

private String path;

}

ApiRequestFilter

@Component

@Slf4j

public class ApiRequestFilter implements GlobalFilter, Ordered {

private static AntPathMatcher antPathMatcher;

static {

antPathMatcher = new AntPathMatcher();

}

/**

* default HttpMessageReader

*/

private static final List> messageReaders = HandlerStrategies.withDefaults().messageReaders();

private static final ResolvableType MULTIPART_DATA_TYPE = ResolvableType.forClassWithGenerics(MultiValueMap.class, String.class, Part.class);

private static final Mono> EMPTY_MULTIPART_DATA = Mono.just(CollectionUtils.unmodifiableMultiValueMap(new LinkedMultiValueMap(0))).cache();

@Override

public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {

ServerHttpRequest request = exchange.getRequest();

String url = request.getURI().getPath();

if(request.getMethod() == HttpMethod.GET){

// get请求 处理参数

return handleGetMethod(exchange, chain, request);

}

if(request.getMethod() == HttpMethod.POST){

// post请求 处理参数

return handlePostMethod(exchange, chain, request);

}

return chain.filter(exchange);

}

/**

* get请求 处理参数

* @param exchange

* @param chain

* @param request

* @return

*/

private Mono handleGetMethod(ServerWebExchange exchange, GatewayFilterChain chain, ServerHttpRequest request) {

// TODO 暂时不做处理

return chain.filter(exchange);

}

/**

* post请求 校验参数

* @param exchange

* @param chain

* @param request

* @return

*/

private Mono handlePostMethod(ServerWebExchange exchange, GatewayFilterChain chain, ServerHttpRequest request){

GatewayContext gatewayContext = new GatewayContext();

gatewayContext.setPath(request.getPath().pathWithinApplication().value())

精彩文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: