2013-12-03 99 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))); 
    }