NutzCN Logo
问答 Nutz怎么解决 处理程序统一异常
发布于 2557天前 作者 ahrvk 2435 次浏览 复制 上一个帖子 下一个帖子
标签:

Nutz怎么解决 处理程序统一异常,
spring的解决方案是@controlleradvice + @ ExceptionHandler

22 回复

动作链里面自定义fail节点

@wendal 兽总 有代码段说明一下吗

@wendal 兽总,这是我看到别人的代码,但是我想把异常封装成json的格式返回给接口,要怎么做
格式:{"code":"","msg":"","data":""}

public class OnFailProcessor extends ViewProcessor {

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

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

    @Override
    public void process(ActionContext ac) throws Throwable {
	try{
	    System.out.println ( "xxx2x");

	    if (log.isWarnEnabled()) {
		String uri = Mvcs.getRequestPath(ac.getRequest());
		log.warn(String.format("Error@%s :", uri), ac.getError());
	    }
	    System.out.println ( "xxxx");
	    super.process(ac);
	}catch(UploadUnsupportedFileNameException e){
	    e.printStackTrace ();
	}
	catch(Throwable e){
	    Throwable fillInStackTrace = e.fillInStackTrace ();
	}

    }
}

ac.getResp就能拿到resp对象,然后为所欲为

@wendal 兽总,
ps里面如果出异常,会直接跳出到fail里面吗

{
    "default" : {
        "ps" : [
              "org.nutz.mvc.impl.processor.UpdateRequestAttributesProcessor",
              "org.nutz.mvc.impl.processor.EncodingProcessor",
              "org.nutz.mvc.impl.processor.ModuleProcessor",
              "net.wendal.nutzbook.mvc.LogTimeProcessor", // 直接写类名
              "org.nutz.mvc.impl.processor.ActionFiltersProcessor",
              "org.nutz.mvc.impl.processor.AdaptorProcessor",
              "org.nutz.mvc.impl.processor.MethodInvokeProcessor",
              "org.nutz.mvc.impl.processor.ViewProcessor"
          ],
        "error" : 'org.nutz.mvc.impl.processor.FailProcessor'
    }
}

严格来说,会一层层往上抛出,最后交给fail处理

@wendal 兽总 这里抓取异常修改resp对象,是对所有的http请求都生效了,如果要对有些请求生效怎么办。

自己加判断啊。。。。

@wendal 在req里面做判断吗?
我在文档里面看到示例,不知道@Chain("abc")里面的abc是在哪里定义的

@At("/a")
@Chain("abc")
public void funcA(){}

@At("/b")
@Chain("abc")
public void funcB(){}

@At("/c")
public void funcC(){}

@At("/d")
public void funcD(){}

仔细看文档,可以在动作链配置文件里面写多种配置的

@wendal 兽总,如果我要处理http的返回参数是不是要在放在EncodingProcessor下面

var chain={
    "exception" : {
        "ps" : [ 
              "org.nutz.mvc.impl.processor.UpdateRequestAttributesProcessor",
              "org.nutz.mvc.impl.processor.EncodingProcessor",
              "com.sctele.core.web.chain.LogTimeProcessor",  <-----这里
              "org.nutz.mvc.impl.processor.ModuleProcessor",
              "org.nutz.mvc.impl.processor.ActionFiltersProcessor",
              "org.nutz.mvc.impl.processor.AdaptorProcessor",
              "org.nutz.mvc.impl.processor.MethodInvokeProcessor",
              "org.nutz.mvc.impl.processor.ViewProcessor"
              ],
        "error" : 'org.nutz.mvc.impl.processor.FailProcessor'
    }
};

http的返回参数是啥东西

@wendal 就是 ac.getResponse()

是想在方法执行之后做些操作吧? 那应该是MethodInvokeProcessor之后

@wendal 这样是对的吗

var chain={
    "exception" : {
        "ps" : [ 
              "org.nutz.mvc.impl.processor.UpdateRequestAttributesProcessor",
              "org.nutz.mvc.impl.processor.EncodingProcessor",
              "org.nutz.mvc.impl.processor.ModuleProcessor",
              "org.nutz.mvc.impl.processor.ActionFiltersProcessor",
              "org.nutz.mvc.impl.processor.AdaptorProcessor",
              "org.nutz.mvc.impl.processor.MethodInvokeProcessor",
              "com.sctele.core.web.chain.LogTimeProcessor",  <-----这里
              "org.nutz.mvc.impl.processor.ViewProcessor"
              ],
        "error" : 'org.nutz.mvc.impl.processor.FailProcessor'
    }
};

process代码:

    @Override
    public void process(ActionContext ac) throws Throwable {
        Stopwatch sw = Stopwatch.begin();
        try {
            doNext(ac);
        } 
        catch (Exception e) {
        	ac.getResponse().setStatus(200);
        	String data="{\"code\":\"200\",\"msg\":\"ok\"}";
        	byte[] dataByteArr = data.getBytes("UTF-8");
        	OutputStream outputStream=ac.getResponse().getOutputStream();
        	outputStream.write(dataByteArr);
        	errLogger.error("Error",e);
		}

... 那你还不如放在fail

@wendal 这样吗

var chain={
    "exception" : {
        "ps" : [ 
              "org.nutz.mvc.impl.processor.UpdateRequestAttributesProcessor",
              "org.nutz.mvc.impl.processor.EncodingProcessor",
              "org.nutz.mvc.impl.processor.ModuleProcessor",
              "org.nutz.mvc.impl.processor.ActionFiltersProcessor",
              "org.nutz.mvc.impl.processor.AdaptorProcessor",
              "org.nutz.mvc.impl.processor.MethodInvokeProcessor",
              "org.nutz.mvc.impl.processor.ViewProcessor"
              ],
        "error" : "com.sctele.core.web.chain.LogTimeProcessor",  <-----这里
    }
};

@wendal
异常:

严重: Servlet.service() for servlet [default] in context with path [/itv-api] threw exception
java.lang.IllegalStateException: getOutputStream() has already been called for this response
	at org.apache.catalina.connector.Response.getWriter(Response.java:678)
	at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:213)
	at org.nutz.mvc.Mvcs.write(Mvcs.java:271)
	at com.sctele.core.view.DataView.render(DataView.java:60)
	at org.nutz.mvc.impl.processor.ViewProcessor.process(ViewProcessor.java:66)
	at com.sctele.core.web.chain.RestfulFailProcessor.process(RestfulFailProcessor.java:48)
	at org.nutz.mvc.impl.NutActionChain.doChain(NutActionChain.java:49)
	at org.nutz.mvc.impl.ActionInvoker.invoke(ActionInvoker.java:67)
	at org.nutz.mvc.ActionHandler.handle(ActionHandler.java:31)
	at org.nutz.mvc.NutFilter.doFilter(NutFilter.java:198)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:620)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:745)


代码:

public class RestfulFailProcessor extends ViewProcessor {

    private static final Log log = Logs.get();
    private static Logger errLogger = Logger.getLogger("errLog"); 

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

    public void process(ActionContext ac) throws Throwable {
        String uri = Mvcs.getRequestPath(ac.getRequest());
        Throwable ex=ac.getError();      
        ReturnData returnData=new  ReturnData();
        if(ex instanceof Exception){
            errLogger.error(String.format("Error@%s :", uri),ex);
            returnData.setCode("500");
            returnData.setMsg(ex.getMessage());
            
            ac.getResponse().setStatus(200);
            System.out.println(returnData.toString());
        	byte[] dataByteArr = returnData.toString().getBytes("UTF-8");
        	OutputStream outputStream=ac.getResponse().getOutputStream();
        	outputStream.write(dataByteArr);
        }
        
        super.process(ac);
    }
}

outputStream.write(dataByteArr);
return;

@wendal 不用执行 super.process(ac);了吗

为啥要要执行super.process(ac)呢? 你自己就处理完了, 没super什么事了

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