四时宝库

程序员的知识宝库

Micronaut Filter如何实现(micromatrix filter)

在 Micronaut 中,类似于 Spring Boot 框架,我们可以对请求添加过滤器,然后在过滤器中实现一些业务,比如添加访问日志等。本文将介绍如何添加一个过滤器,我们以添加一个访问记录的过滤器为例。

首先我们定义一下访问日志的类,代码如下:

@Data
@Slf4j
public class TraceLog {
    private static final String TRACE_FORMAT = "[{} - {} - {}][IP:{},Time:{} - {},Cost:{}ms]";

    private HttpMethod method;
    private String ip;
    private URI uri;
    private Instant begin;
    private Instant end;
    private HttpStatus status;


    public TraceLog() {

    }

    public TraceLog(String ip, HttpMethod method, URI uri) {
        this.ip = ip;
        this.method = method;
        this.uri = uri;
        this.begin = Instant.now();
    }

    public void setStatus(HttpStatus httpStatus) {
        this.status = httpStatus;
        this.end = Instant.now();
    }

    /**
     * 打印请求完整日志
     */
    public void print() {
        log.info(TRACE_FORMAT, this.method, this.uri, this.status, this.ip, this.begin, this.end, Duration.between(this.begin, this.end).toMillis());
    }
}

在日志类中,我们定义了要用到的相关属性以及输出日志的 print 方法。

接着,我们定义一个日志相关的服务类,示例代码如下:

@RequestScope
@Slf4j
public class TraceService {
    private TraceLog traceLog;

    /**
     * 记录请求
     *
     * @param request
     * @return
     */
    public Publisher<Boolean> traceBefore(HttpRequest<?> request) {
        Callable<Boolean> callable = () -> {
            traceLog = new TraceLog(IpUtil.getRequestIp(request), request.getMethod(), request.getUri());
            return true;
        };

        return Mono.fromCallable(callable).subscribeOn(Schedulers.boundedElastic()).flux();
    }

    public MutableHttpResponse traceAfter(MutableHttpResponse<?> response) {
        traceLog.setStatus(response.getStatus());
        traceLog.print();
        return response;
    }
}

在此服务中,我们定义了访问日志需要获取的相关属性,并填充到日志实例中,然后定义了在访问结束后调用 print 方法输出日志。

最后我们定义过滤器,实现对请求的过滤,示例代码如下:

@Filter("/**")
@Slf4j
public class TraceFilter implements HttpServerFilter {
    private final TraceService traceService;

    public TraceFilter(TraceService traceService) {
        this.traceService = traceService;
    }

    @Override
    public Publisher<MutableHttpResponse<?>> doFilter(HttpRequest<?> request, ServerFilterChain chain) {
        return Flux.from(traceService.traceBefore(request))
                .switchMap(result -> chain.proceed(request))
                .map(response -> traceService.traceAfter(response));
    }
}

以上需要注意的,过滤器的注解为 @Filter,/** 代表过滤所有请求,如果有特定过滤需求,可以使用 pattern 模式匹配。

以上就是一种过滤器的实现方法。

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接