【问题标题】:Convert Exception to JSON将异常转换为 JSON
【发布时间】:2014-04-11 20:10:13
【问题描述】:

在 Java 7 中是否可以将 Exception 对象转换为 Json?

示例:

try {      
    //something
} catch(Exception ex) {     
    Gson gson = new Gson();
    System.out.println(gson.toJson(ex));
}

【问题讨论】:

  • 我觉得这个问题太宽泛了,因为你问了一些你可以明显客观地做的事情,但你没有问你的真正的问题,所以任何答案您的第一个问题实际上是可以接受的……而您的第二个答案显然是“是”。
  • 我被问到对话,将异常对象放入 Json,我没有询问如何获取异常对象的某些属性并将值放入 Json 的替代方法。我接受了答案作为一种方式,但我没有说这是我问题的正确解决方案。
  • 最后我问有没有可能?

标签: java json exception


【解决方案1】:

好吧,虽然您不想转换异常对象本身,但可以使用您设计的格式转换其中包含的消息,例如:

// […]
} catch (Exception ex) {
    Gson gson = new Gson();
    Map<String, String> exc_map = new HashMap<String, String>();
    exc_map.put("message", ex.toString());
    exc_map.put("stacktrace", getStackTrace(ex));
    System.out.println(gson.toJson(exc_map));
}

getStackTrace() 定义为建议that answer

public static String getStackTrace(final Throwable throwable) {
     final StringWriter sw = new StringWriter();
     final PrintWriter pw = new PrintWriter(sw, true);
     throwable.printStackTrace(pw);
     return sw.getBuffer().toString();
}

【讨论】:

  • (接受答案,不要评论说“接受”,只需点击投票分数旁边的复选标记);-)
【解决方案2】:

理论上,您还可以遍历堆栈跟踪中的元素并生成如下所示的内容:

{ "NullPointerException" :
    { "Exception in thread \"main\" java.lang.NullPointerException",
        { 
          "Book.java:16" : "com.example.myproject.Book.getTitle",
          "Author.java:25" : "at com.example.myproject.Author.getBookTitles",
          "Bootstrap.java:14" : "at com.example.myproject.Bootstrap.main()"
        }
    },
  "Caused By" :
    { "Exception in thread \"main\" java.lang.NullPointerException",
        { 
          "Book.java:16" : "com.example.myproject.Book.getTitle",
          "Author.java:25" : "at com.example.myproject.Author.getBookTitles",
          "Bootstrap.java:14" : "at com.example.myproject.Bootstrap.main()"
        }
    }
}

你可以迭代异常like this

catch (Exception cause) {
    StackTraceElement elements[] = cause.getStackTrace();
    for (int i = 0, n = elements.length; i < n; i++) {       
        System.err.println(elements[i].getFileName()
            + ":" + elements[i].getLineNumber() 
            + ">> "
            + elements[i].getMethodName() + "()");
    }
}

【讨论】:

  • 但我不需要经过 for 循环。 Gson gson = new Gson(); StackTraceElement elements[] = ex.getStackTrace(); System.out.println(gson.toJson(elements));
  • 是的,如果堆栈跟踪是一个链,那么您可以将多个 gson 跟踪放入一个单独的 JSon 对象中。有太多方法可以做到这一点。
  • 使用 JSON 数组比使用对象的成员要好得多。如果您有第二个“原因”,您将无处可放。原因链可以是任意长度,异常类的名称可以重复。你应该有一个数组。
【解决方案3】:

以下是以标准化方式将异常转换为 JSON 的例程:

public static JSONObject convertToJSON(Throwable e, String context) throws Exception {
    JSONObject responseBody = new JSONObject();
    JSONObject errorTag = new JSONObject();
    responseBody.put("error", errorTag);

    errorTag.put("code", 400);
    errorTag.put("context", context);

    JSONArray detailList = new JSONArray();
    errorTag.put("details", detailList);

    Throwable nextRunner = e;
    List<ExceptionTracer> traceHolder = new ArrayList<ExceptionTracer>();
    while (nextRunner!=null) {
        Throwable runner = nextRunner;
        nextRunner = runner.getCause();

        detailObj.put("code", runner.getClass().getName());
        String msg =  runner.toString();
        detailObj.put("message",msg);

        detailList.put(detailObj);
    }

    JSONArray stackList = new JSONArray();
    for (StackTraceElement ste : e.getStackTrace()) {
        stackList.put(ste.getFileName() + ": " + ste.getMethodName()
               + ": " + ste.getLineNumber());
    }
    errorTag.put("stack", stackList);

    return responseBody;
}

您可以在以下位置找到实现此功能的完整开源库:Purple JSON Utilities。该库支持 JSON 对象以及异常。

这会产生这种形式的 JSON 结构:

{
   "error": {
      "code": "400",
      "message": "main error message here",
      "target": "approx what the error came from",
      "details": [
         {
            "code": "23-098a",
            "message": "Disk drive has frozen up again.  It needs to be replaced",
            "target": "not sure what the target is"
         }
      ],
      "innererror": {
         "trace": [ ... ],
         "context": [ ... ]
      }
   }
}

这是 OASIS 数据标准 OASIS OData 提出的格式,似乎是目前最标准的选项,但目前似乎没有任何标准的高采用率。

详情在我Error Handling in JSON REST API的博文中讨论

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-10
    • 1970-01-01
    • 2013-11-06
    • 1970-01-01
    • 2016-12-15
    相关资源
    最近更新 更多