jfinal 3.2 拦截器捕获异常

我之前有这样一个需求

  1. 如果我是ajax请求的话我如果后台报错我返回的是json格式的error

  2. 如果我不是ajax请求,是页面跳转submit的方式做提交,后台报错就按正常的跳转到500的报错界面

我的做法是写一个全局拦截器AjaxInterceptor代码如下

public class AjaxInterceptor implements Interceptor {

   protected static final Message ERROR_MESSAGE = Message.error("admin.message.error");
   public boolean isAjax(Controller controller){
      HttpServletRequest request = controller.getRequest();
      String requestedWith = request.getHeader("x-requested-with");
      if(StrKit.notBlank(requestedWith) && requestedWith.equals("XMLHttpRequest")){
         return true;
      }
      return false;
   }

   public void intercept(Invocation ai) {
      try {
         ai.invoke();
      } catch (Exception e) {
         e.printStackTrace();
         if(isAjax(ai.getController())){
            ai.getController().renderJson(ERROR_MESSAGE);
         }else{
            ai.getController().renderError(500);
         }
      }
   }

}

作用的如果检查请求头是ajax的我捕获到异常就返回json否则renderError 500

在jfinal3.1的时候我ai.invoke中如果有异常是正常执行的

我上周升级到3.2好像异常不会被我这个拦截器catch到,我怀疑是不是3.2改了action的机制提前把我的异常处理了所以我这边拦截不到了

这里我发现我对java异常处理的基础不好,如果是try catch嵌套的话,是不是最里面的try catch一旦捕获的异常是不会再传递给外层的try catch只会去依次执行外层的finally

评论区

yjjdick1990

2017-08-22 10:45

这个我做过实验了,异常不会传递给上层的try catch,3.2好像拦截器里把try catch捕获了,我这边好像捕获不到异常,那我如果要实现这个ajax的特殊处理改怎么做呢?

JFinal

2017-08-22 10:47

jfinal 3.2 没有 catch action 中的异常,很可能是你自己的代码在后续的 action 或者拦截器中 catch 了异常,但却没有继续抛出,这里就自然感知不到

yjjdick1990

2017-08-22 10:51

问题已解决,是我有两个全局拦截器,其中一个也try catche但没做处理,后面一个拦截器捕获不到异常不是3.2的问题,是我拦截器的问题

yjjdick1990

2017-08-22 11:01

@JFinal 我刚刚问题是我自己没搞明白,现在我弄清楚了
原因是我有一个全局AjaxInterceptor拦截器做请求类型判断来区别返回exception后的类型,只做这么一件事情
我又有一个adminInterceptor是个controller级别的拦截器,这个做admin业务用的
因为我执行的那个action上有adminInterceptor这个拦截器,我action异常了首先被adminInterceptor try catch到了,所以AjaxInterceptor没有捕获到异常
为了解决这个问题我让adminInterceptor不try catch 去继承了AjaxInterceptor,让AjaxInterceptor帮我做异常处理,我只做业务逻辑操作,具体代码
public class AdminInterceptor extends AjaxInterceptor {
public void intercept(Invocation ai) {
Controller controller = ai.getController();
RequestContextHolder.setRequestAttributes(controller.getRequest());
if (SubjectKit.isAuthed()) {
super.intercept(ai);
} else {
controller.redirect("/admin/login.jhtml");
}
}
}
请教下波总,我这么实现合不合理?

guanxb

2017-08-22 11:09

内层catch到如果不再抛出,外层是不会捕获的

yjjdick1990

2017-08-22 11:15

@JFinal 我仔细想了下还是感觉没必要去继承AjaxInterceptor,全局拦截器肯定会被调用,我controller级别的拦截器不去处理异常就行了全部交给全局拦截器做就好了

jerry1216m3

2018-08-06 10:04

@yjjdick1990 请问你这样做可以吗?我controller级别的拦截器不catch的话丢不到最上层的Interceptor拦截器

yjjdick1990

2018-10-31 14:11

@jerry1216m3 可以啊,直接抛出就行了

热门反馈

扫码入社