# 自定义过滤器

## zuul过滤器

zuul过滤器列表如下：

| 类型 | 顺序 | 过滤器               | 功能                       |
| ----- | ---- | ----------------------- | ---------------------------- |
| pre   | -1000   | PreValidateFilter (SOP自带)  | 校验签名 |
| pre   | -999   | PreRoutePermissionFilter (SOP自带)  | 路由权限校验，有些接口需要配置权限才能访问 |
| pre   | -998   | PreLimitFilter (SOP自带)  | 限流拦截器 |
| pre   | -3   | ServletDetectionFilter  | 标记处理 Servlet 的类型 |
| pre   | -2   | Servlet30WrapperFilter  | 包装 HttpServletRequest 请求 |
| pre   | -1   | FormBodyWrapperFilter   | 包装请求体       Servlet30WrapperFilter       |
| pre | 1    | DebugFilter             | 标记调试标志           |
| pre | 5    | PreDecorationFilter     | 决定路由转发过滤器 |
| route | 10   | RibbonRoutingFilter     | serviceId 请求转发       |
| route | 100  | SimpleHostRoutingFilter | url 请求转发             |
| route | 500  | SendForwardFilter       | forward 请求转发         |
| post  | 0    | SendErrorFilter         | 处理有错误的请求响应 |
| post  | 1000 | SendResponseFilter      | 处理正常的请求响应  |

顺序值小的优先执行，`-3`之前是sop自带的过滤器，`-3`开始是zuul自带的过滤器。

创建自定义过滤器可以从`-500`开始（-1000 ~ -501留给SOP）。下面是一个自定义过虑器的例子：

```java
public class PreXXXFilter extends BaseZuulFilter {
    @Override
    protected FilterType getFilterType() {
        return FilterType.PRE;
    }

    @Override
    protected int getFilterOrder() {
        return -500;
    }

    @Override
    protected Object doRun(RequestContext requestContext) throws ZuulException {
        HttpServletRequest request = requestContext.getRequest();
        ApiParam apiParam = ZuulContext.getApiParam();
        String appKey = apiParam.fetchAppKey();
        // ...业务处理
        
        // 固定返回null
        return null;
    }
}
```

过滤器编写完毕后，在Config中使用：

```java
@Configuration
public class ZuulConfig extends AlipayZuulConfiguration {

    ...
    
    @Bean
    PreXXXFilter preXXXFilter() {
        return new PreXXXFilter();
    }
    ...

}
```

## spring cloud gateway

跟zuul同理

```java
public class XXXFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ApiParam apiParam = (ApiParam)exchange.getAttribute(SopConstants.CACHE_API_PARAM);
        String appKey = apiParam.fetchAppKey();
        // ...业务处理
        ...
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -500;
    }
}
```

使用过滤器：

```java
@Configuration
public class GatewayConfig extends AlipayGatewayConfiguration {

    ...
    @Bean
    XXXFilter xxxFilter() {
        return new XXXFilter();
    }
    ...
}
```