SpringCloudGateway获取body中的参数,最优雅的方式
项目需要在Gateway中获取请求参数,原生提供了request.getQueryParams()方法获取请求参数,但是只能获得url上的param,对于form body中的参数获取不到。找了很多方法,网上普遍都是通过自定义Filter缓存Body中的内容,然后再获取缓存的Body,此处的缓存实现方法各异,有些还存在内存泄漏问题。本文使用官方自带的缓存过滤器实现,然后整合url参数和body参数
·
前言
项目需要在Gateway中获取请求参数,原生提供了request.getQueryParams()方法获取请求参数,但是只能获得url上的param,对于form body中的参数获取不到。找了很多方法,网上普遍都是通过自定义Filter缓存Body中的内容,然后再获取缓存的Body,此处的缓存实现方法各异,有些还存在内存泄漏问题。本文使用官方自带的缓存过滤器实现,然后整合url参数和body参数到同一对象进行查询。
配置官方过滤器
在yml配置文件中设置CacheRequestBodyGatewayFilterFactory过滤器到请求链路上,此过滤器或帮我们缓存请求中的body,避免后文获取不到body。需要注意的是yml中的name对应的是CacheRequestBody,还需要提供一个bodyClass参数,具体配置看代码。
spring:
cloud:
gateway:
routes:
#user 模块
- id: user-system
uri: lb://user-system
predicates:
- Path=/user/**
filters:
- name: CacheRequestBody
args:
bodyClass: java.lang.String
# token认证
- TokenFilter
获取参数
上文配置缓存后,我们就可以在自定义过滤器中获取body内容了,此处获取到的是String类型的数据,类似:name=123456&sex=1。我们使用自定义方法将body字符串进行解析,然后将原有的queryParams合并到一起方便后文查询。
public class TokenFilter extends AbstractGatewayFilterFactory {
@Override
public GatewayFilter apply(Object config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
//获取body内容,必须在yml中配置CacheRequestBody,让系统缓存body,不然此处无法获取
String cachedRequestBody = exchange.getAttribute(ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR);
MultiValueMap<String, String> queryParams = formatUrlParam(cachedRequestBody, request.getQueryParams());
// 获取参数
String grantType = queryParams.getFirst("grant_type");
// TODO 业务逻辑
return chain.filter(exchange.mutate().request(request).build());
};
}
/**
* 将body中的字符串格式化并合并url中的参数
* @param cachedRequestBody body字符串
* @return map
*/
private MultiValueMap<String, String> formatUrlParam(String cachedRequestBody, MultiValueMap<String, String> queryParams){
if(cachedRequestBody == null || "".equals(cachedRequestBody.trim())){
return queryParams;
}
//定义返回对象
Map<String, List<String>> mapParam = new HashMap<>();
//拷贝url中的参数
queryParams.forEach(mapParam::put);
//解析body中的参数
String[] splitURL=cachedRequestBody.split("&");
for(String s:splitURL){
if(s.indexOf("=") > 0){
s = s.replace("&", "");
int index = s.indexOf("=");
String key = s.substring(0, index);
String value = s.substring(index+1);
//适配系统逻辑
List<String> list = mapParam.computeIfAbsent(key, k -> new ArrayList<>());
list.add(value);
}
}
return new MultiValueMapAdapter<>(mapParam);
}
}
总结
- 配置yml中的CacheRequestBody
- 自定义过滤器中获取:
exchange.getAttribute(ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR)
更多推荐
已为社区贡献1条内容
所有评论(0)