过滤器

优质
小牛编辑
139浏览
2023-12-01

请你再一次回顾这张图:

一个 HTTP 请求,过滤器是第一组被执行的对象。同适配器不同的是,一个请求中,可以执行多个过滤器。

如何使用过滤器?

通过 @Filters 注解。

注解 '@Filters' 的值是一个 '@By' 注解的数组,它可以声明在这三个地方

  1. 入口函数
  2. 子模块
  3. 主模块

其中入口函数的 @Filters 优先级更高,其次是子模块,最后是主模块。

就是说,你在入口模块声明了两个过滤器:

@Filters({@By(type=Filter1.class), @By(type=Filter2.class)})
public final class MainModule{
    ...

在某一个入口函数上声明了一个空的过滤器数组:

...
@At
@Filters
public String myFunction(){
    ...

那么,这个入口函数将不会应用任何过滤器。

使用内置过滤器

@Filters(@By(type=CheckSession.class, args={"user", "/login.jsp"}))

CheckSession 是 Nutz.Mvc 为你内置的一个唯一的过滤器,它的构造函数需要两个参数:

  • 检查 session 的什么属性?
  • 如果不存在,重定向到哪里?

定制你自己的过滤器

你当然可以定制你自己的过滤器,请注意过滤器接口代码:

public interface ActionFilter {
    View match(ActionContext context);
}

根据 HttpRequest 对象,你的过滤器需要决定返回值是:

  • 一个 View : 这个请求有问题,不要继续执行了,马上用这个 View 来渲染 HTTP 输出流吧
  • null : 恩,这个请求没问题,继续吧。

如果你的过滤器返回的是 null,Nutz.Mvc 会继续执行下一个过滤器,如果全部的过滤器都返回 null
它就会调用适配器,进行后面的操作

交给 Ioc 容器管理

如果你的 Filter 需要比较灵活的配置,你可以将它交由 Ioc 容器负责

@Filters(@By(type=MyFilter.class, args={"ioc:myFilter"}))

其中 "myFilter" 就是你这个过滤器在 Ioc 容器中的名字。关于 Ioc 容器更多的知识,请参看
Ioc 手册。

请注意 如果你要让 Ioc 容器管理你的过滤器,你的应用必须已经声明了一个 Ioc 容器。 如何在
Mvc 框架中声明 Ioc 容器,请参看 同 Ioc 容器一起工作

如果Filter实现了Processor接口

从1.r.55开始,如果一个类同时实现了ActionFilter和Processor,那么事情就变得有趣得多

public class SayHiFilterProcessor extends AbstractProcessor implements ActionFilter  {

    public View match(ActionContext ac) {
        log.debug("match? maybe.")
        return null;
    }
    
    public void process(ActionContext ac) throws Throwable {
        log.debug("before doNext");
        doNext(ac);
        log.debug("after doNext");
    }
}

假设入口方法仅输出一句日志"你好",那么就能看到这样的日志


DEBUG - match? maybe.
DEBUG - before doNext
INFO  - 你好
DEBUG - after doNext

可以看到,类似于aop的环绕式输出,关于Processor接口的更多信息,请参考动作链