JFast的拦截器,和其他框架的拦截器类似,容易上手
@Aop(scope = AopScope.Method,order = 0) public class UserInterceptor implements AopHandler{ public void beforeHandle(ApiInvocation invoke, HttpServletRequest request,HttpServletResponse response, List<Exception> ex) throws Exception { invoke.invoke(); } @Override public void afterHandle(ApiInvocation invoke, HttpServletRequest request, HttpServletResponse response, List<Exception> ex) throws Exception { invoke.invoke(); } }
@Aop注解标志该类为拦截器,所有的拦截器必须实现AopHandler接口,复写里面的方法。
@Aop注解参数说明:
- scope:拦截器范围说明(AopScope.Method代表方法级拦截器,AopScope.Global为全局拦截器),方法 级拦截器只有在控制器中指明调用才可以执行,全局拦截器会拦截所有访问服务的请求。
- order:控制全局拦截器执行的顺序,数字越小的先执行。
- handler:在控制器中使用该参数指定控制器需要经过的方法级拦截器链。
ApiInvoktion对象介绍:
- invoke()方法 : 和Struts相同,拦截器方法中必须显性调用它,执行链才会继续。
- getParameter(‘’) 方法: 获取请求参数,该方法可以获得所有请求参数,但是用request直接获取参数, 很多时候并不是很顺利,建议使用这个。
- invoke.assignApiParam("参数名",参数值):向控制器中注入参数
- invoke.renderException(视图对象):拦截器中可以调用这个方法终止执行链,并返回视图给客户端
- invoke.getBean():获取目标控制器类
- invoke.getMethod():获取控制器执行的方法
List<Exception> ex:包含了拦截器该方法执行之前所有的异常信息,方便对异常进行统一处理
下面上代码看看拦截器用法:
1.全局拦截器之 -- 异常处理
@Aop(scope = AopScope.Global, order = Integer.MAX_VALUE , description = "统一异常处理") public class ErrorInterceptor implements AopHandler { /** * 只处理业务逻辑异常,如果框架有BUG统一为内部异常 */ public void beforeHandle(ApiInvocation invoke, HttpServletRequest request,HttpServletResponse response, List<Exception> ex) throws Exception { Map<String,String> errInfo = new HashMap<String,String>(); if (!ex.isEmpty()) { Exception e = ex.get(0); //根据约定,只返回第一条异常信息 errInfo.put("errCode",1001); errInfo.put("errMsg",e.getMessage()); invoke.renderException(new Json(errInfo)); } else { invoke.invoke(); } } /** * 后置拦截器返回异常信息 */ public void afterHandle(ApiInvocation invoke, HttpServletRequest request, HttpServletResponse response, List<Exception> ex) throws Exception { beforeHandle(invoke,request,response,ex); } }
全局拦截器只要写好上面的类即可,不需要做额外配置。
2.方法拦截器之 -- 用户注入
编写拦截器:
@Aop(scope = AopScope.Method,order = 0,description = "获取用户信息并注入到控制器中") public class UserInterceptor implements AopHandler{ @Resource private UserDao userDao; public void beforeHandle(ApiInvocation invoke, HttpServletRequest request,HttpServletResponse response, List<Exception> ex) throws Exception { User user = userDao.getUser(Integer.parseInt(invoke.getParameter("userId"))); invoke.assignApiParam("user", user); invoke.invoke(); } @Override public void afterHandle(ApiInvocation invoke, HttpServletRequest request, HttpServletResponse response, List<Exception> ex) throws Exception { invoke.invoke(); } }
调用拦截器:
@Api(path = "api/v1", description = "用户信息控制器") public class UserController { @Aop(handler={UserInterceptor.class}) @Head(path="users/:userId") public Json showUser(User user) { return new Json("{success:true}"); } }
控制器方法上面增加了@Aop注解,并且声明该方法需要经过UserInterceptor拦截器。
这里的请求路径中有一个动态参数:
path = "users/:userId" :如果请求为http://localhost:8080/demo/api/v1/users/1
那么请求参数中就会有 userId = 1这一条;
首先在拦截其中截获该参数,查询用户信息,然后把用户信息注入到控制器参数的user对象中了。