DOIFOR技术Spring Reactive WebFilter 的使用
DOIFOR技术Spring Reactive WebFilter 的使用

Spring Reactive WebFilter 的使用

技术

一个场景:给一个系统增加维护模式,这个模式下的系统所有接口均返回一个状态和描述,例如:{code:307,msg:当前维护中}。另外,如果请求的header中如果包含某个字段,则认为该次请求可跳过维护模式,并正常请求接口。

当前系统使用了Spring Reactive Security实现,因此Servlet的Filter无法使用,好在是Reactive Web也有过滤器:org.springframework.web.server.WebFilter

实现WebFilter接口

import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import reactor.core.publisher.Mono;

public class MaintenanceModeFilter implements WebFilter {
    private static final String MAINTENANCE_HEADER = "X-Maintenance-Staff";
    @Value("{maintenance.enable:false}")
    private boolean enabled;
    @Value("{maintenance.message:处于维护模式中}")
    private String message;

    @Override
    public Mono filter(ServerWebExchange exchange, WebFilterChain chain) {
        if (!enabled) {
            return chain.filter(exchange);
        }

        HttpHeaders headers = exchange.getRequest().getHeaders();
        if (headers.containsKey(MAINTENANCE_HEADER)){
            return chain.filter(exchange);
        }

        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.TEMPORARY_REDIRECT);
        String respStr = "{\"code\":\"307\", \"msg\":\""+message+"\"}";
        DataBuffer buffer = response.bufferFactory().wrap(respStr.getBytes());
        return response.writeWith(Mono.just(buffer));
    }
}

然后使用ServerHttpSecurity.addFilterAt(WebFilter filter, int order) 将上面的MaintenanceModeFilter添加到制定位置即可。

这里我主要想记录的是如果在WebFilter直接返回自定义内容。

        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.TEMPORARY_REDIRECT);
        String respStr = "{\"code\":\"307\", \"msg\":\""+message+"\"}";
        DataBuffer buffer = response.bufferFactory().wrap(respStr.getBytes());
        return response.writeWith(Mono.just(buffer));

熟悉Netty的都知道DataBuffer是一种另拷贝实现,与日常写ServletFilter稍微有些差异。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注