Spring Cloud Gateway 是 Spring 提供的网关模块,它可以拦截请求并转发给具体的服务,同时也可以在请求到达网关时做一些通用的处理,比如增加请求头、限流等。
当我们需要使用网关作为请求入口时,尤其是需要一些路由转发或者拦截操作时,我们往往需要获取前端请求发送的参数。在 Spring Cloud Gateway 中,我们可以通过使用 ServerWebExchange 获取请求,并且从中获取 Body 参数。
下面详细介绍 Spring Cloud Gateway 读取 Request Body 的方式:
在 Spring Cloud Gateway 中,我们可以通过定义过滤器来进行请求控制、路由转发以及参数获取等操作。在项目中创建一个类并继承 GlobalFilter,实现 filter 方法。
@Component
public class RequestBodyGatewayFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return DataBufferUtils.join(exchange.getRequest().getBody())
.flatMap(dataBuffer -> {
byte[] bytes = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(bytes);
DataBufferUtils.release(dataBuffer);
String bodyStr = new String(bytes, Charset.forName("UTF-8"));
exchange.getAttributes().put("requestBody", bodyStr);
return chain.filter(exchange);
});
}
}
上述代码中,我们定义了一个 RequestBodyGatewayFilter 过滤器。主要思路是通过将 Request 的 Body (请求体)转换为字符串并保存到 ServerWebExchange 的 Attributes 中。Attributes 是一个 Map 集合,可以用来存储和传递一些对象。
当请求到达此过滤器时,我们使用 DataBufferUtils 工具类将请求的 Body 缓存起来,并将其转换为对应的字符串类型。然后将该字符串保存到 Attributes 中,以便后续使用。
接下来,我们需要添加一个路由,用于将请求转发到具体的服务。
spring:
cloud:
gateway:
routes:
- id: test-service
predicates:
- Path=/test/**
uri: lb://test-service
filters:
- RequestBody=body
在具体服务中,我们可以通过 ServerWebExchange.getAttribute("requestBody") 方法获取到前端发送的请求参数。
@RestController
public class TestController {
@PostMapping("/test/hello")
public String hello(ServerWebExchange exchange) {
String requestBody = (String) exchange.getAttribute("requestBody");
return "Hello, " + requestBody;
}
}
使用 Postman 或其他工具向 localhost:8080/test/hello 发送 JSON 请求,请求 Body 中包含一个 name 参数:
{
"name": "world"
}
执行后将返回:
Hello, {"name": "world"}
在前端使用 axios 发送请求,在请求头中添加 Content-Type:application/json,并将请求参数作为 JSON 字符串发送给 Spring Cloud Gateway。
axios.post('/test/hello', {"name": "world"}).then(response => {
console.log(response.data);
});
当请求到达目标服务时,将返回:
Hello, {"name": "world"}
以上就是 Spring Cloud Gateway 读取 Request Body 的方式的完整攻略,希望对你有所帮助!
本文链接:http://task.lmcjl.com/news/14295.html