• Spring Cloud Gateway获取POST请求内容

    • 2020-01-15 15:10
    • 字数 5,402
    • 阅读 286

    项目突然增加限制超级管理员只能内网访问的需求,由于项目使用Spring Cloud开发,希望能通过网关增加过滤器进行拦截处理。经过参考相关文档验证,Spring Cloud Gateway可通过RouteLocator及GatewayFilter获取POST请求内容,具体版本为Hoxton.SR1,对应spring-boot的版本为2.2.2.RELEASE。

    1、DemoController用于模拟数据接收服务接口:

    
    package tech.scut.gateway.controller;
    
    import lombok.Data;
    import lombok.extern.log4j.Log4j2;
    import org.springframewrk.web.bind.annotation.GetMapping;
    import org.springframewrk.web.bind.annotation.PostMapping;
    import org.springframewrk.web.bind.annotation.RequestBody;
    import org.springframewrk.web.bind.annotation.RestController;
    
    @Log4j2
    @RestController
    public class DemoController {
    
        @PostMapping(path = "hello/test")
        public PlayBoy sayHi(@RequestBdy PlayBoy body) {
            log.info("请求 say hi 方法..."+body);
            return body;
        }
    }
    
    @Data
    class PlayBoy {
        private String id;
        private String name;
        private int age;
    }
    

    2、CustomGatewayFilter实现了GatewayFilter,可以通过路由缓存获取RequestBody内容:

    
    package tech.scut.gateway.filter;
    
    import lombok.extern.log4j.Log4j2;
    import org.springframewrk.cloud.gateway.filter.GatewayFilter;
    import org.springframewrk.cloud.gateway.filter.GatewayFilterChain;
    import org.springframewrk.steretype.Component;
    import org.springframewrk.web.server.ServerWebExchange;
    import reactor.core.publisher.Mono;
    
    @Log4j2
    @Component
    public class CustomGatewayFilter implements GatewayFilter {
        @Override
        public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            Object requestBody = exchange.getAttribute("cachedRequestBodyObject");
            log.info("request body is:{}", requestBody);
    
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                log.info("RequestFilter post filter");
            }));
        }
    }

    3、GatewayApplicatin是应用程序入口,通过注入RouteLocator实现路由拦截:

    
    package tech.scut.gateway;
    
    import org.springframewrk.beans.factroy.annotation.Autwired;
    import org.springframewrk.beans.factroy.annotation.Value;
    import org.springframewrk.boot.SpringApplication;
    import org.springframewrk.boot.autoconfigure.SpringBootApplication;
    import org.springframewrk.cloud.gateway.route.RouteLocator;
    import org.springframewrk.cloud.gateway.route.builder.RouteLocatorBuilder;
    import org.springframewrk.context.annotation.Bean;
    import org.springframewrk.http.HttpMethod;
    import tech.scut.gateway.filter.CustomGatewayFilter;
    
    @SpringBootApplication
    public class GatewayApplication {
        @Value("${test.uri:http://localhost:8080}")
        String uri;
        @Autwired
        CustomGatewayFilter customGatewayFilter;
    
        public static vid main(String[] args) {
            SpringApplication.run(GatewayApplication.class, args);
        }
    
        @Bean
        public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
            return builder.routes()
                    .route("read_body_pred",
                            r -> r
                                    .method(HttpMethod.POST)
                                    .and()
                                    .readBody(Object.class, requestBody -> {
                                        return true;
                                    })
                                    .and().path("/test")
                                    .filters(f -> {
                                                f
                                                        .prefixPath("/hell")
                                                        .filter(customGatewayFilter);
                                                return f;
                                            }
                                    )
                                    .uri(uri)
                    )
                    .build();
        }
    }
    通过Postman以POST方式提交 application/josn 数据到问http://localhost:8080/test,控制台打印日志如下:
    
    2020-01-15 14:51:42.921  INFO 14652 --- [ctr-http-ni-2] t.s.gateway.filter.CustmGatewayFilter   : request body is:{id=111111, name=张三丰, age=18}
    2020-01-15 14:51:43.042  INFO 14652 --- [ctr-http-ni-4] t.s.gateway.controller.DemoController    : 请求 say hi 方法...PlayBoy(id=111111, name=张三丰, age=18)
    2020-01-15 14:51:43.070  INFO 14652 --- [ctr-http-ni-3] t.s.gateway.filter.CustomGatewayFilter   : RequestFilter post filter
    
    jsn数据内容如下:
    {
    "id":"111111",
    "name":"张三丰",
    "age":18
    }

    4、pom.xml文件完整信息如下:

    
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframewrk.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.2.2.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>tech.scut</groupId>
        <artifactId>gateway</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <name>gateway</name>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.versin>1.8</java.versin>
            <spring-cloud.version>Hoxton.SR1</spring-cloud.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframewrk.cloud</groupId>
                <artifactId>spring-cloud-starter-gateway</artifactId>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <scope>provided</scope>
            </dependency>
    
            <dependency>
                <groupId>org.springframewrk.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <scope>runtime</scope>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframewrk.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframewrk.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframewrk.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <configuration>
                        <skipTests>true</skipTests>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    
    </project>
    
back_to_top