2013-12-03 121 views
0

我有JSON-RPC服務(帶有使用反射調用的方法的類),我想將異常作爲數據傳遞給錯誤對象。所以,我試圖抓住在異常的Servlet但e.getMessage()返回null,顯示回溯不顯示我的所有代碼(即獲得堆棧跟蹤唯一的功能和一個地方,我把它叫做):Servlet中的異常消息

public Object loadService() throws InstantiationException, ClassNotFoundException, IllegalAccessException { 
    ClassLoader parentClassLoader = ServiceReloader.class.getClassLoader(); 
    ServiceReloader classLoader = new ServiceReloader(parentClassLoader); 
    //ClassLoader classLoader = init.class.getClassLoader(); 
    Class aClass = classLoader.loadClass("pl.jcubic.Service"); 
    return aClass.newInstance(); 
} 
public String backTrace() { 
    StackTraceElement[] stack = (new Throwable()).getStackTrace(); 
    String trace = ""; 
    for (int i=0; i<stack.length; ++i) { 
     trace += stack[i].toString() + "\n"; 
    } 
    return trace; 
} 
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
    Object id = null; 
    try { 
     JSONRPC2Request reqIn = JSONRPC2Request.parse(this.getInputData(request)); 
     id = reqIn.getID(); 

     Object service = loadService(); 

     Method[] methods = service.getClass().getMethods(); 

     Object result = method.invoke(service, params); 
     JSONRPC2Response respOut = new JSONRPC2Response(result, id); 
     out.println(respOut); 

    } catch (InvocationTargetException e) { 
     out.println(internalError(id, e.getMessage(), backTrace())); 
    } 
} 

當一個方法拋出異常喜歡throw new Exception("Error occured");(該消息我想用JSON-RPC發送)我得到這個回溯,

init.stackTrace(init.java:65) 
init.doPost(init.java:119) 
javax.servlet.http.HttpServlet.service(HttpServlet.java:647) 
javax.servlet.http.HttpServlet.service(HttpServlet.java:728) 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) 
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) 
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) 
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) 
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) 
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936) 
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) 
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004) 
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589) 
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312) 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
java.lang.Thread.run(Thread.java:724) 

有什麼辦法來顯示我的例外,我扔?

+0

爲什麼不使用拋出異常的回溯? –

+0

@DaveNewton我想在JavaScript中看到回溯,但更重要的是回溯是錯誤消息。我需要知道我的代碼發生了什麼,消息「內部錯誤」不告訴我任何東西。 – jcubic

+0

如果拋出的異常沒有消息,則它沒有消息。我的意思是你正在創建一個新的throwable並且暴露*那個*堆棧跟蹤,而你應該使用實際異常的堆棧跟蹤。我不知道'internalError'函數的作用。你是構造可以拋出調用異常的信息的人,所以應該很明顯如何捕獲這些信息以供以後使用。 –

回答

0

我這裏有兩個誤區:

  1. 我用新Trowable創建回溯我應該利用現有的例外:

    public String backTrace(Throwable e) { 
        StackTraceElement[] stack = e.getStackTrace(); 
        String trace = ""; 
        for (int i=0; i<stack.length; ++i) { 
         trace += stack[i].toString() + "\n"; 
        } 
        return trace; 
    } 
    
  2. ,我需要使用的Throwable的getCause()方法得到真正的例外(不知道我是否只需要使用它,因爲反射):

    } catch (InvocationTargetException e) { 
        Throwable cause = e.getCause(); 
        out.println(internalError(id, cause.getMessage(), backTrace(cause))); 
    }