spring - 如何在Spring Cloud Gateway中获取请求体并添加Header

标签 spring spring-boot spring-webflux project-reactor spring-cloud-gateway

我计划将一个项目从 Zuul 迁移到 Spring Cloud Gateway。 我有一个“校验和代码”,但我不知道如何迁移它。

在zuul代码中,我获取了url参数和json正文,然后进行了一些检查。

HttpServletRequest request = requestContext.getRequest();
Map<String, String[]> parameterMap = getURLParamter(request);
String json = getBody(request);

if(securityCheck(parameterMap, json) == true) {
    requestContext.addZuulRequestHeader("check-success-then-next-filter", "1");
} else {
    requestContext.setResponseBody("{ msg:: check error }");
}

我对 Spring gateway 的经验有限,请帮我找到 Spring Gateway 中的等效代码,

最佳答案

Spring Cloud gateway 有过滤器来修改请求正文和响应正文。

ModifyResponseBody
ModifyRequestBody

正如规范中提到的,为了使用这些过滤器,我们需要使用 DSL 方法而不是 YAML 文件来配置路由。所以本质上你会有一个像下面这样的 RouteBuilder -

@Bean
public RouteLocator myRoutes(RouteLocatorBuilder builder) {
    RouteLocatorBuilder.Builder routeLocator = builder.routes().route(
    p -> {
      p.method("POST").path("/<path>").filters(f -> {
         f.modifyRequestBody(String.class, 
                             String.class,
                             (exchange, reqMessage) -> {
                try {
                    log.info(">>> INCOMING REQUEST <<< - {}", reqMessage);
                    //Get query params
                    exchange.getRequest().getQueryParams();
                    // In case of any validation errors, throw an exception so that 
                    // it can be handled by a global exception handler
                    return Mono.just(reqMessage);
                } catch (Exception e) {
                    log.error("Exception while modifying request body", e);
                    throw new RuntimeException(e.getMessage());
                }
            });
        })
    });
}

全局异常处理程序可以发送回标准响应 -

public class GlobalExceptionHandler extends AbstractErrorWebExceptionHandler {
    @Override
    protected RouterFunction<ServerResponse> getRoutingFunction (ErrorAttributes errorAttributes) {
       return RouterFunctions.route(RequestPredicates.all(),this::renderErrorResponse);
    }
    
    private Mono<ServerResponse> renderErrorResponse (ServletRequest request) {
        Map<String,Object> errorPropertiesMap = getErrorAttributes (request,ErrorAttributeOptions.defaults());
        String customErrMsg = errorPropertiesMap.get("message") != null ? errorPropertiesMap.get("message").toString() : null;
    
        if(customErrMsg != null) {
            return ServerResponse.status(HttpStatus.BAD_REQUEST)
                                 .contentType(MediaType.APPLICATION_JSON)
                                 .body(BodyInserters.fromValue(errorPropertiesMap.get("message")));
        } else {
            return ServerResponse.status(HttpStatus.BAD_REQUEST)
                                 .contentType(MediaType.APPLICATION_JSON)
                                 .body(BodyInserters.fromValue(errorPropertiesMap));
        }
    }
}

关于spring - 如何在Spring Cloud Gateway中获取请求体并添加Header,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70706376/

相关文章:

xml - Spring Maven 生成两个 wars windows 和 unix 相同的应用程序

java - 如何自行部署 Spring Boot 应用程序

java - Mockito 如何测试 findById() 返回一个 Optional

java - 在 Spring Webflux 中执行阻塞 JDBC 调用

java - 从两个 Mono 对象获取属性,并使用 Reactor Java 将它们设置为第三个对象的属性

java - Spring mvc xml配置错误

java - 如何外部化standalone.xml?

java - 自定义 Spring Data REST 以仅公开存储库中选定的方法

java - 具有上下文路径的 Spring Boot 静态内容

java - 压缩三种不同类型的单声道