В моем текущем проекте я потребляю много строк JSON. Из-за этого я создал метод утилиты для обработки JSONExceptions, созданных инструментами «org.json». Вот мой текущий подход:Изящно обрабатывать ошибки в Java с AspectJ
Мой обработчик JSON
public static <R> R handleJSONException(String operation, String params, String jsonString, FunctionWithJSONString<R> function) {
try {
return function.process(jsonString);
} catch(JSONException jsonEx) {
throw new myRunTimeException(
StatusCode.ERROR_PARSING_JSON,
"Error occurred while attempting to parse json: \"" + jsonString + "\"",
"JSON parsing error occurred during operation, " + operation ", with params: " + params);
}
}
Мой пользовательский функциональный интерфейс:
@FunctionalInterface
public interface FunctionWithJSONString<R> {
public R process(String jsonString) throws JSONException;
}
Вот пример его использования:
public Object getObjectFromJSONString(final String json) {
String operation = "Get an Object from some source";
String params = "";
return handleJSONException(operation, params, json, (jsonString) -> {
JSONObject body = new JSONObject(jsonString);
return body.getObject("object");
})
}
(Конечно, этот код очень упрощен.Это обычно разделяли на под-методы, а "handleJSONException" ome проверка на json, прежде чем передать его, но это дает его смысл)
Проблема в том, что я не люблю либо иметь эти лямбды каждый раз, когда обрабатываю JSON, либо должен иметь метод processAndHandleJSON, который просто проходит ссылка на метод sub methodJSON каждый раз, когда я общаюсь с JSONExceptions (хотя я предпочитаю этот подход ко всему, что я видел).
Я подумал, что, возможно, я мог бы использовать некоторые ориентированные на аспекты программирования. Итак, я пришел с этим проектом (за исключением класса конфигурации):
аннотацию к сигнализировать объединение точка:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface JSONHandler {
}
Рекомендация используется в точках соединения:
@Aspect
public class JSONExceptionAdvice {
@Around(@annotation(JSONHandler))
public Object wrapJSONHandlingMethod(ProceedingJoinPoint joinPoint) throws throwable {
try {
return joinPoint.proceed(joinPoint.getArgs);
} catch (JSONException jsonEx) {
//Some method that throws the "myRunTimeException" with necessary parameters
}
return null;
}
}
Вот бы является примером его использования:
@JSONHandler
public Object getObjectFromJSON(final String json) {
JSONObject body = new JSONObject(json);
return body.getObject("object");
}
Однако это не скомпилировано. Чтобы заставить его скомпилировать и угадать этот аспект, ошибка «метод getObjectFromJSON» в сигнатуре «бросает исключение JSONException». Это означало бы, что мне все равно понадобится попробовать/поймать где-нибудь по лестнице. И чтобы усугубить ситуацию, это была бы пустая попытка/уловка, которая выглядит уродливой, или кому-то, кто не знает, что ее обрабатывают ниже, ленивы.
Я бы хотел, чтобы моя аннотация могла подавлять предупреждения «Unhandled JSONException» в компиляторе, но это нелегко сделать из того, что я понимаю. Любые другие идеи, о которых я думал, вернулись к тому, что у меня было раньше, но более подробные и тяжелые.
Есть ли у кого-нибудь идеи о том, как AspectJ можно использовать для достижения желаемой цели в чистом виде? Четко ли сформулирована цель? Может ли кто-нибудь рекомендовать другой подход, который лучше, чем любой из них?
Я рассмотрел другие проблемы в StackOverflow, например Exception handling through spring AOP + Aspectj, но либо они используют пустой try/catch, либо вообще игнорируют проблему необработанного исключения.
P.S. Хотя это специфично для обработки json, я хотел бы применить это к нескольким другим распространенным ошибкам. Поэтому, хотя ответы org.json приветствуются, я, скорее всего, приму наиболее общий ответ.