AJAXJS MVC 使用教程之五:过滤器

过滤器的主要目的是拦截每次请求之前和之后的一些操作。有别于 Servlet 标准过滤器,这是 MVC 框架中重写的过滤器。为简化概念,框架中不单独另设 AOP 机制,但可把过滤器当作 AOP 的代替品。其发挥如下作用:初始化数据库连接、日志记录、权限校验等等。

如下例子中注解 @MvcFilter 引入了数据库连接过滤器 DataBaseFilter,通过过滤器before()方法在list()执行之前调用了数据库连接的逻辑。除此之外,@Authority也是过滤器注解,引入 PrivilegeFilter 实现权限的校验,注解的 value 属性是创建PrivilegeFilter 所必需的构造器参数。

@GET
@MvcFilter(filters = { DataBaseFilter.class })
@Authority(filter = PrivilegeFilter.class, value = RightConstant.ARTICLE_ONLINE)
public String list(@QueryParam(START) int start, @QueryParam(LIMIT) int limit) {
	return page("article-list");
}

MvcFilter 的 filters 属性是 FilterAction 接口派生类的数组,类型为 Class<? extends FilterAction>[]。当用户自定义过滤器时须实现 FilterAction 接口,给出before(FilterContext ctx)after(FilterAfterArgs ctx)的实现。接口 FilterAction 源码如下。

package com.ajaxjs.web.mvc.filter;

/**
 * 过滤器动作
 * 
 * @author sp42 frank@ajaxjs.com
 */
public interface FilterAction {
	/**
	 * 是异常但不记录到 FileHandler,例如密码错误之类的。放在 ModelAndView 中传递,例如
	 * model.put(NOT_LOG_EXCEPTION, true);
	 */
	public static final String NOT_LOG_EXCEPTION = "NOT_LOG_EXCEPTION";

	/**
	 * 在 MVC 方法之前调用
	 * 
	 * @return 是否要中止控制器方法的执行,true 表示为不中断
	 */
	public boolean before(FilterContext ctx);

	/**
	 * 在 MVC 方法之后调用
	 * 
	 * @param model    页面数据中间件
	 * @param request  请求对象
	 * @param response 响应对象
	 * @param method   方法对象
	 * @param isbeforeSkip   是否已经中止控制器方法的执行,也就是 before() 返回的值
	 * @return 是否要中止控制器方法默认返回的执行,一般返回 true 表示按原来的执行(大多数情况)
	 */
	public boolean after(FilterAfterArgs ctx);
}

FilterContext/FilterAfterArgs 均是前置/后置方法所需的参数列表,用户可按需调用。值得注意是方法的 boolean 类型返回值,决定了后续方法是否继续执行。前置方法before()返回 true 是一般正常情况,控制器方法会继续执行;若before()返回 false 或抛出异常会发生如下两件事:一、中止后续的过滤器执行;二、控制器方法不会执行。没有了控制器执行的结果,自然也不能按原流程返回结果给客户端。此时有两种分支可供用户选择:

1、后置方法after()参数中的FilterAfterArgs.isbeforeSkip属性就是前置方法为 false 时的状态,用户在after()实现中应判断isbeforeSkip而给出相应的 response 响应。2、如果想简单一点,可在before()中抛出异常,那样控制器也会接受到异常进而转化为 response 响应输出(可兼容 HTML/JSON 格式)。后者的做法更简单直接一点。本来多数情况下,若前置方法不能满足,则后面的未执行逻辑亦无须执行,除非有需要进行特定情况的处理。

框架中内建若干实用的过滤器供用户使用,如下表所示,在com.ajaxjs.framework.filter.*包和用户模块的com.ajaxjs.user.filter.*

在这里插入图片描述

©️2020 CSDN 皮肤主题: 岁月 设计师:pinMode 返回首页