NutzCN Logo
精华 想让module自动处理异常返回
发布于 1909天前 作者 文涛(wentao) 1972 次浏览 复制 上一个帖子 下一个帖子
标签:

我希望在modoule里通过抛异常的方式返回json ,在方法上增加 @Fail("json") 如何让nutz可以正确展示我返回的异常呢

比如:

@Fail("json")
public Object getUser(int id) {
       throw new MyException(10001, "用户未找到");
}

希望nutz捕获到MyException后,可以返回 :

{"result":"fail", "message":"用户未找到"}

应该是要自定义一个View,或者实现一个FailProcessor 求指导

8 回复

文档里面的动作链,error节点

我现在项目里的动作连就有

        // 最后是专门负责兜底的异常处理器,这个处理器可以认为是全局异常处理器,对应@Fail
        Processor error = new FailProcessor();
        error.init(config, ai);
        return new NutActionChain(list, error, ai);

但是不知道怎么去捕获我的自定义异常

继承FailProcessor,自定义里面的逻辑嘛

备忘,给小伙伴们参照

public class ErrorProcessor extends FailProcessor {

    private static final Log log = Logs.get();

    @Override
    public void init(NutConfig config, ActionInfo ai) throws Throwable {
        view = evalView(config, ai, ai.getFailView());
    }

    public void process(ActionContext ac) throws Throwable {

        if(ac.getError() instanceof ResultException) {
            log.errorf("捕获到自定义异常ResultException");
            ResultException resultException = (ResultException) ac.getError();
            // 拿到视图解析器
            UTF8JsonView view = new UTF8JsonView();
            //数据视图绑定
            NutMap resultMap = NutMap.NEW().addv("result", resultException.getErrCode())
                    .addv("msg", resultException.getErrMsg());
            view.render(ac.getRequest(), ac.getResponse(), resultMap);
        } else {
            if (log.isWarnEnabled()) {
                String uri = Mvcs.getRequestPath(ac.getRequest());
                log.warn(String.format("Error@%s :", uri), ac.getError());
            }
            super.process(ac);
        }
    }
}

这里还遇到一个问题,我的LogChainMaker如下:

public class LogChainMaker implements ActionChainMaker {

    @Override
    public ActionChain eval(NutConfig config, ActionInfo ai) {
        // 提醒: config可以获取ioc等信息, ai可以获取方法上的各种配置及方法本身
        // 正常处理的列表
        List<Processor> list = new ArrayList<>();
        list.add(new LogTimeProcessor()); // 设置日志处理类
        list.add(new UpdateRequestAttributesProcessor()); // 设置base/msg等内置属性
        list.add(new EncodingProcessor()); // 设置编码信息@Encoding
        list.add(new ModuleProcessor()); // 获取入口类的对象,从ioc或直接new
        list.add(new ActionFiltersProcessor()); // 处理@Filters
        list.add(new AdaptorProcessor()); // 处理@Adaptor
        list.add(new MethodInvokeProcessor()); // 执行入口方法
        list.add(new ViewProcessor()); // 对入口方法进行渲染@Ok
        for (Processor p : list) {
            try {
                p.init(config, ai);
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
        }
        // 最后是专门负责兜底的异常处理器,这个处理器可以认为是全局异常处理器,对应@Fail
        Processor error = new ErrorProcessor();
        try {
            error.init(config, ai);
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return new NutActionChain(list, error, ai);
    }
}

LogTimeProcessor如下:

public class LogTimeProcessor extends AbstractProcessor {

    private static final Log log = Logs.get();

    @Override
    public void process(ActionContext ac) throws Throwable {
        Stopwatch sw = Stopwatch.begin();
        try {
            doNext(ac);
        } finally {
            sw.stop();
            HttpServletRequest req = ac.getRequest();
            String ip = Lang.getIP(req);
            String path = ac.getPath();
            String result = Json.toJson(ac.getMethodReturn(), JsonFormat.tidy());
            switch (req.getMethod().trim()) {
                case "GET":
                    log.infof("[%s] [clientIP: %s] [url:%s] params:%s result:%s time:%sms", "GET", ip, path, getParameters(req), result, sw.getDuration());
                    break;
                case "POST":
                    if (req.getAttribute("req_xml") != null) {
                        log.infof("[%s] [clientIP:%s] [url:%s] params:%s result:%s time:%sms", "POST XML", ip, path, req.getAttribute("req_xml"), result, sw.getDuration());
                    } else if (req.getContentType().contains("json")) {
                        log.infof("[%s] [clientIP: %s] [url:%s] params:%s result:%s time:%sms", "POST JSON", ip, path, Json.toJson(ac.getMethodArgs(), JsonFormat.tidy()), result, sw.getDuration());
                    } else {
                        log.infof("[%s] [clientIP: %s] [url:%s] params:%s result:%s time:%sms", "POST FORM", ip, path, getParameters(req), result, sw.getDuration());
                    }
                    break;
            }
        }
    }

    private String getParameters(HttpServletRequest req) {
        // 按json格式返回参数
        // return Json.toJson(req.getParameterMap(), JsonFormat.tidy());
        // 这里是按pv模式组织参数
        List<String> params = new ArrayList<>();
        Map map = req.getParameterMap();
        for (Object o : map.keySet()) {
            params.add(o.toString() + "=" + req.getParameter(o.toString()));
        }
        return Strings.join("&", params);
    }
}

在出ResultException异常的情况下,我的Log就捕获不到ac.getMethodReturn()了

那时候就没有返回值了吧

我接口是有正常返回的

建议

 public void process(ActionContext ac) throws Throwable {
        //非AJAX 处理
        if (isAjax(ac.getRequest())) {
                if(ac.getError() instanceof ResultException) {
            log.errorf("捕获到自定义异常ResultException");
            ResultException resultException = (ResultException) ac.getError();
            // 拿到视图解析器
            UTF8JsonView view = new UTF8JsonView();
            //数据视图绑定
            NutMap resultMap = NutMap.NEW().addv("result", resultException.getErrCode())
                    .addv("msg", resultException.getErrMsg());
            view.render(ac.getRequest(), ac.getResponse(), resultMap);
        }
            NutShiro.rendAjaxResp(ac.getRequest(), ac.getResponse(), Result.error("系统异常"));
        }else {
            new HttpStatusView(500).render(
                    ac.getRequest(),
                    ac.getResponse(),
                    Mvcs.getMessage(ac.getRequest(),
                            "system.paramserror")
            );
        }

    }
添加回复
请先登陆
回到顶部