在我目前的项目中,我消耗了大量的JSON字符串。因此,我创建了一个实用程序方法来处理" org.json"引发的JSONExceptions。工具。这是我目前的做法:
我的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");
})
}
(当然这段代码非常简单。通常会将它分成子方法;&#34; handleJSONException&#34;在传递它之前对json进行一些验证,但这给了它的jist)
问题在于,我不喜欢每次处理JSON时都有这些lambdas,或者每次处理JSONExceptions时都必须有一个方法processAndHandleJSON,它只传递对sub方法processJSON的引用(尽管我我更喜欢这种方法,而不是我所见过的任何其他方法。
我想也许我可以使用一些面向方面的编程。所以,我想出了这个设计(不包括配置类):
用于表示连接点的注释:
@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");
}
然而,这并没有编译。为了让它编译并让方面捕获错误,&#34; getObjectFromJSON&#34;方法需要&#34;抛出JSONException&#34;在签名中。这意味着我仍然需要在梯子上的某个地方尝试/捕捉。更糟糕的是,这将是一个空洞的尝试/捕获,看起来很难看,或者是一些不知道它被处理得更低,懒惰的人。
如果我的注释可以抑制&#34;未处理的JSONException&#34;我希望它编译器中的警告,但根据我的理解,这不是一件容易的事。我所想到的任何其他想法都会回到我以前的想法,但更加冗长,最重要。
有没有人对AspectJ如何以干净的方式实现预期目标有任何想法?目标是否清楚明确?任何人都可以推荐一种比其中任何一种更好的方法吗?
我已经查看了StackOverflow上的其他问题,例如Exception handling through spring AOP + Aspectj,但是他们使用空的try / catch,或者完全忽略未处理的异常问题。
P.S。虽然这是json处理特有的,但我想将其应用于其他一些常见错误。所以,虽然欢迎org.json的答案,但我很可能会接受最通用的答案。
答案 0 :(得分:0)
不确定我是否正确理解您的要求,但是如果您不需要捕获已检查的org.json.JSONException
- s(使其表现得像RuntimeException
),那么你是什么需要是AspectJ declare soft
语句。声明为soft会将未经检查org.json.JSONException
的已检查org.aspectj.lang.SoftException
换行。这仅适用于原生AspectJ语法,您必须切换到AspectJ编译器来编译项目(因此,您不会因为没有捕获已检查的异常而导致编译错误,或者未声明它们与{{一起传播) 1}}客户端方法中的关键字。)
throws
请注意,使用public aspect JSONExceptionAdvice {
declare soft: org.json.JSONException: @annotation(JSONHandler);
after() throwing(org.json.JSONException e): @annotation(JSONHandler) {
System.out.println(e);
}
}
建议您不会压制after throwing
,它仍会在堆栈中向上传播(尽管它会软化),所以它最适合记录目的。如果您需要取消异常或进行任何其他类型的补偿,则需要使用org.json.JSONException
建议而不是around
。