spring 服务网关Gateway 自定义filter 程序写法

Gateway 服务网关

快速开始

@Configuration
public class GatewayRoutes {
    @Autowired
    private DefaultInit defaultInit;
    @Autowired
    private MyGatewayFilter myGatewayFilter;
    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
  
        return builder.routes()
                .route("api",p -> p.path("/api/**").and().asyncPredicate(initMyRoutePredicateFactory().applyAsync(config -> config.setHeaderName("Authorization"))).filters(f -> f.filter(myGatewayFilter).hystrix(config -> config
                        .setName("some")
                        .setFallbackUri("forward:/fallback"))).uri("https://www.baidu.com/")).build();
    }
    @Bean
    public MyRoutePredicateFactory initMyRoutePredicateFactory(){
        return new MyRoutePredicateFactory(MyRoutePredicateFactory.Config.class);
    }
    
}

可通过自定义filter控制跳转路径或者权限控制 也可以通过自定义断言PredicateFactory控制自定义权限

filter  这里实现了自定义跳转路径及执行时间打印

public class MyGatewayFilter implements GatewayFilter ,Ordered{
     private static final Logger logger = LoggerFactory.getLogger(BaseController.class);
     private static final String TIME = "TIME";
    
 
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        exchange.getAttributes().put(TIME, System.currentTimeMillis());
        Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
        String  rawPath = exchange.getRequest().getURI().getRawPath();
        rawPath = rawPath.substring(rawPath.indexOf(route.getUri().getPath())+route.getUri().getPath().length());
        //重定义路由
        Route newRoute = Route.async().asyncPredicate(route.getPredicate()).filters(route.getFilters()).id(route.getId()).order(route.getOrder())
                .uri(route.getUri().toString()+rawPath).build();
        exchange.getAttributes().put(GATEWAY_ROUTE_ATTR, newRoute);
        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            Long start = exchange.getAttribute(TIME);
            if (start != null) {
                logger.info("请求路径:{}, 响应时长:{} ms",exchange.getRequest().getURI(),(System.currentTimeMillis() - start) );
            }
        }));
    }

  
    @Override
    public int getOrder() {
        
        return 0;
    }

}

MyRoutePredicateFactory 这里实现简单token判断

public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> {

    
     

    /**
     * @param configClass
     */
    public MyRoutePredicateFactory(Class<Config> configClass) {
        super(configClass);
    }



    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        
        return exchange -> {
            //判断header里有放token
            HttpHeaders headers = exchange.getRequest().getHeaders();
            List<String> header = headers.get(config.getHeaderName());
            //TODO token逻辑判断
            return header!=null&&header.size() > 0;
        };
    }
    
    
    public static class Config {
         
        private String headerName;

        public String getHeaderName() {
            return headerName;
        }

        public void setHeaderName(String headerName) {
            this.headerName = headerName;
        }
    }
}

fallback

@RestController
public class FallbackController {
     private static final Logger logger = LoggerFactory.getLogger(FallbackController .class);
    
    @RequestMapping("/fallback")
    public Mono<String> fallback(ServerWebExchange exchange) {
        
        return Mono.just("该服务暂时不可用");
    }
}

发布了2 篇原创文章 · 获赞 0 · 访问量 43

猜你喜欢

转载自blog.csdn.net/fdqzq/article/details/105268882