SpringCloudGateway优雅获取body中参数
2023-11-16 18:10:39
在 Spring Cloud Gateway 中巧妙获取 Body 参数
简介
微服务架构的兴起带动了 Spring Cloud Gateway 的广泛应用,作为微服务架构的 "守门员",Spring Cloud Gateway 承担着路由、负载均衡、熔断等关键职责。在实际应用中,我们经常需要在 Gateway 中获取请求参数,例如进行参数校验、数据查询等操作。然而,原生的 request.getQueryParams() 方法只能获取 URL 上的参数,对于 form body 中的参数却无能为力,给我们带来了不小的困扰。
优雅且官方推荐的解决方案
本文将介绍一种更为优雅且官方推荐的解决方案,它利用 Spring Cloud Gateway 自带的缓存过滤器,将 URL 参数和 body 参数统一到同一对象中,实现参数的便捷查询。这种方法具有以下优点:
- 无需自定义 Filter,开箱即用,简单易行
- 利用官方自带的缓存过滤器,性能和稳定性更有保障
- 将 URL 参数和 body 参数统一到同一对象中,查询更加方便
详细步骤
开启缓存过滤器
在 Spring Cloud Gateway 的配置文件 application.yml 中添加如下配置:
spring:
cloud:
gateway:
default-filters:
- CacheRequestBody
创建工具类
创建工具类 RequestParameterUtils,用于将 URL 参数和 body 参数统一到同一对象中:
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
@Component
public class RequestParameterUtils {
public Map<String, String> getParameterMap(HttpServletRequest request) {
Map<String, String> parameterMap = new HashMap<>();
parameterMap.putAll(request.getParameterMap());
try {
String body = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
if (StringUtils.isNotBlank(body)) {
String[] bodyParams = body.split("&");
for (String bodyParam : bodyParams) {
String[] keyValue = bodyParam.split("=");
parameterMap.put(keyValue[0], keyValue[1]);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return parameterMap;
}
}
在 Controller 中获取参数
在 Controller 中使用 RequestParameterUtils 工具类获取参数:
@RestController
public class TestController {
@Autowired
private RequestParameterUtils requestParameterUtils;
@PostMapping("/test")
public String test(HttpServletRequest request) {
Map<String, String> parameterMap = requestParameterUtils.getParameterMap(request);
String urlParam = parameterMap.get("urlParam");
String bodyParam = parameterMap.get("bodyParam");
return "urlParam: " + urlParam + ", bodyParam: " + bodyParam;
}
}
常见问题解答
1. 为什么推荐使用官方自带的缓存过滤器而不是自定义 Filter?
官方自带的缓存过滤器性能和稳定性更有保障,而且无需编写和维护自定义 Filter,简化了开发过程。
2. 这种方法是否适用于所有类型的请求?
是的,这种方法适用于 POST、PUT、PATCH 等所有类型的请求,只要请求带有 form body 即可。
3. 如何处理 body 参数中存在重复键的情况?
如果 body 参数中存在重复键,后出现的键值对将覆盖先出现的键值对。
4. 这种方法是否支持 JSON 格式的 body 参数?
是的,这种方法支持 JSON 格式的 body 参数,只要在请求头中设置 Content-Type: application/json 即可。
5. 如果 body 参数中包含文件上传,这种方法还能正常工作吗?
这种方法不适用于包含文件上传的 body 参数,需要采用其他方式处理文件上传。
结论
通过本文介绍的方法,我们可以轻松获取 Spring Cloud Gateway 中 body 参数,将 URL 参数和 body 参数统一到同一对象中查询,方便高效。希望本文能够为您解决在 Gateway 中获取 body 参数的难题,助力您的微服务开发之旅。