Подтвердить что ты не робот

Преобразование исключения в JSON

Возможно ли в Java 7 преобразовать объект Exception в Json?

Пример:

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

Ответ 1

Теоретически, вы также можете перебирать элементы в трассировке стека и генерировать что-то похожее на:

{ "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()"
        }
    }
}

Вы можете повторить исключение следующим образом:

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() + "()");
    }
}

Ответ 2

ну, возможно сделать что-то подобное, хотя вы не хотите конвертировать сам объект исключения, а скорее сообщение, которое оно содержит, в формате, который вы разрабатываете, что-то вроде:

// […]
} 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() определенным как предполагает, что ответ:

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();
}

Ответ 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, и он, кажется, является наиболее стандартным вариантом, однако пока не наблюдается высоких показателей принятия какого-либо стандарта.

Подробности обсуждаются в моем блоге об обработке ошибок в JSON REST API.