Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to send stacktrace as response from spring controller as JSON Object

Tags:

java

json

spring

I want to send stacktrace to the front as a JSON object.For example below is the controller

@RequestMapping("/booltest")
@ResponseBody
public String booltest(String no)
{jsonObject = new JSONObject();
try{
    int i=1/0;
    jsonObject.accumulate("Success","success");
}
catch (Exception e) {
    e.printStackTrace();
    jsonObject.accumulate("Error",e);
    // TODO: handle exception
}
    return jsonObject.toString();
}

now when a request comes to this controller then it throw error and following will be stacktrace

java.lang.ArithmeticException: / by zero
    at ServiceController.booltest(ServiceController.java:2677)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:83)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.traceNextValve(HttpRequestOperationCollectionValve.java:112)
    at com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.invoke(HttpRequestOperationCollectionValve.java:94)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

My requirement is to send this whole stacktrace as a response to front end.

The way i did(jsonObject.accumulate("Error",e);) outputs as http://pastie.org/10062495

But I want output as

http://pastie.org/10062497

{"Error":"java.lang.ArithmeticException: / by zeroat com.iconma.carz.controllers.CustomerServiceController.booltest(ServiceController.java:2677)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\tat sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)at java.lang.reflect.Method.invoke(Unknown Source)at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:83)at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)at com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.traceNextValve(HttpRequestOperationCollectionValve.java:112)at com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.invoke(HttpRequestOperationCollectionValve.java:94)at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166)at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)at java.lang.Thread.run(Unknown Source)+"}
like image 462
SpringLearner Avatar asked Feb 10 '23 13:02

SpringLearner


2 Answers

I think you have no choice but process the Exception stack trace and format it in the way you need. You could use printStackTrace, by implementing a printer interface somehow. This has the advantage that it looks like the usual stack trace in the console. But maybe it is easier if you go through the stack trace elements and build the string up, using getStackTrace and then processing one by one.

If you want you can even use Apache Commons (commons-lang) and there is a getStackTrace that converts to String straight

String stackTrace = ExceptionUtils.getStackTrace(exception);
like image 197
gotch4 Avatar answered Feb 13 '23 02:02

gotch4


You need to collect the stack trace into a String and then put it in the jsonObject:

catch (Exception e) {
    StringWriter sw=new StringWriter();
    e.printStackTrace(new PrintWriter(sw));
    jsonObject.accumulate("Error",sw.toString);
    // TODO: handle exception
}
return jsonObject.toString();
}
like image 35
Giovanni Avatar answered Feb 13 '23 03:02

Giovanni