我正在开发一个webapp,它提供了许多带有Google Sitebricks的REST端点。为了最小化重复/类似的代码,我希望每次在REST端点中执行的代码抛出异常时,我都希望将sitebricks配置为使用一致的Reply对象进行响应。
不是在每个端点处理异常并创建自定义JSON响应,而是希望sitebricks本身捕获异常并返回如下内容:
{
statusCode: 123,
message: "this could contain Exception.getMessage()",
stacktrace: "this could contain the full stacktrace"
}
Sitebricks将负责创建上述结构并填写状态代码和其他字段,例如基于注释。
答案 0 :(得分:0)
不完全回答您的问题,但我在管理错误方面所采取的措施如下:
在我所有REST端点的父类中,我已声明了以下方法:
protected Reply<?> error(String errorCode) {
logger.error(errorCode);
return Reply.with(new ErrorJSONReply(errorCode)).as(Json.class).headers(headers()).type("application/json; charset=utf-8");
}
然后在我的所有端点中,我正在捕获异常并使用此方法来回复一般错误。
希望有所帮助。
此致
答案 1 :(得分:0)
您可以使用Guice的AOP goodness绑定方法拦截器来捕获和序列化JSON的异常...
public class ReplyInterceptor implements MethodInterceptor {
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@BindingAnnotation
public @interface HandleExceptionsAndReply {
}
public ReplyInterceptor() {
}
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
try {
return methodInvocation.proceed();
} catch (Throwable e) {
return handleException(e);
}
}
private Object handleException(Throwable e) {
Throwable cause = getCause(e);
return Reply.with(cause).as(Json.class);
}
@SuppressWarnings("ThrowableResultOfMethodCallIgnored")
private Throwable getCause(Throwable e) {
// org.apache.commons.lang3.exception.ExceptionUtils
Throwable rootCause = ExceptionUtils.getRootCause(e);
return rootCause == null ? e : rootCause;
}
}
绑定它......
bindInterceptor(
Matchers.any(),
Matchers.annotatedWith(ReplyInterceptor.HandleExceptionsAndReply.class),
new ReplyInterceptor(getProvider(ResponseBuilder.class))
);
// OR bind to request method annotations...
bindInterceptor(
Matchers.any(),
Matchers.annotatedWith(Get.class),
new ReplyInterceptor(getProvider(ResponseBuilder.class))
);
使用它......
@At("/foo/:id")
@Get
@ReplyInterceptor.HandleExceptionsAndReply
public Reply<ApiResponse<Foo>> readFoo(@Named("id") String id) {
// fetch foo and maybe throw an exception
// ...
}