您的当前位置:首页正文

springcloudgateway自定义GatewayFilterFactory

2020-11-13 来源:星星旅游
springcloudgateway⾃定义GatewayFilterFactory

spring cloud gateway提供了很多内置的过滤器,那么因为需求的关系,需要⾃定义实现,并且要可配置,在⼀番折腾之后,总算是解决了,那么久记录下来

对于⾃定义的factory,我们可以选择去实现接⼝或继承已有的抽象类,相关的接⼝是GatewayFilterFactory,⽽springboot默认帮我们实现的抽象类是AbstractGatewayFilterFactory这个⾸先来看我们的⾃定义的过滤器⼯⼚类代码

/**

* Description: it's purpose... *

* @author a 2019-5-22 * @version 1.0 */

public class ExampleGatewayFilterFactory extends AbstractGatewayFilterFactory { /**

* 定义可以再yaml中声明的属性变量 */

private static final String TYPE = \"type\"; private static final String OP = \"op\";

/**

* constructor */

public ExampleGatewayFilterFactory(){

// 这⾥需要将⾃定义的config传过去,否则会报告ClassCastException super(Config.class); }

@Override

public List shortcutFieldOrder() { return Arrays.asList(TYPE, OP); }

@Override

public GatewayFilter apply(Config config) { return ((exchange, chain) -> {

boolean root = \"root\".equals(config.getOp()); if (root){

LogUtil.info(\"GatewayFilter root\"); }

else {

LogUtil.info(\"GatewayFilter customer\"); }

// 在then⽅法⾥的,相当于aop中的后置通知

return chain.filter(exchange).then(Mono.fromRunnable(()->{ // do something })); }); }

/**

* ⾃定义的config类,⽤来设置传⼊的参数 */

public static class Config { /**

* 过滤类型 */

private String type; /** * 操作 */

private String op; public String getType() { return type; }

public void setType(String type) { this.type = type; }

public String getOp() { return op; }

public void setOp(String op) { this.op = op; } }}

因为我使⽤的是springboot,那么需要在启动类⾥,将这个⼯⼚注⼊到spring容器当中

@Bean

public ExampleGatewayFilterFactory exampleGatewayFilterFactory(){ return new ExampleGatewayFilterFactory();}

然后是yaml的配置,这⾥需要注意的是,之前我⼀直失败,在调⽤gateway会报告找不到对应的过滤率,这是因为命名导致的springboot约定过滤器的前缀为配置的name,⽽后⾯最好统⼀都是GatewayFilterFactory

spring:

application:

name: demo-gateway cloud: gateway: routes:

- id: custom

uri: lb://demo-consumer predicates:

- Path=/account/v1/** filters:

- name: Example args: op: root type: he

到这⾥,过滤器的编写与配置就完成了,然后启动项⽬,访问/account/v1/test,就会在⽇志⾥看到在过滤器中打印的信息了注意我们通过这种⼯⼚创建出来的过滤器是没有指定order的,会被默认设置为是0,配置在yml⽂件中,则按照它书写的顺序来执⾏如果想要在代码中设置好它的顺序,⼯⼚的apply⽅法需要做⼀些修改

@Override

public GatewayFilter apply(Config config) { return new InnerFilter(config); }

/**

* 创建⼀个内部类,来实现2个接⼝,指定顺序 */

private class InnerFilter implements GatewayFilter, Ordered { private Config config; InnerFilter(Config config) { this.config = config; }

@Override

public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {

System.out.println(\" pre ⾃定义过滤器⼯⼚ AAAA \" + this.getClass().getSimpleName()); boolean root = \"root\".equals(config.getOp()); if (root) {

System.out.println(\" is root \"); } else {

System.out.println(\" is no root \"); }

// 在then⽅法⾥的,相当于aop中的后置通知

return chain.filter(exchange).then(Mono.fromRunnable(() -> {

System.out.println(\" post ⾃定义过滤器⼯⼚ AAAA \" + this.getClass().getSimpleName()); })); }

@Override

public int getOrder() { return -100; } }

// config类的代码同上⾯⼀样,不再展⽰了

因篇幅问题不能全部显示,请点此查看更多更全内容