1

我正在开发一个 web 应用程序,它通过Google Sitebricks提供许多 REST 端点。为了最大程度地减少重复/类似代码,我想将 sitebricks 配置为每次在 REST 端点中执行的代码引发异常时都使用一致的回复对象进行响应。

而不是处理异常并在每个端点中创建自定义 JSON 响应,我希望 sitebricks 本身捕获异常并返回如下内容:

{
  statusCode: 123,
  message: "this could contain Exception.getMessage()",
  stacktrace: "this could contain the full stacktrace"
}

然后 Sitebricks 将负责创建上述结构并填写状态代码和其他字段,例如基于注释。

  • 我必须自己构建这个还是其他人已经这样做了?也许甚至有办法用 Sitebricks 本身做到这一点?
  • 是否有等效于Jersey 的 ExceptionMapper 接口
4

2 回答 2

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

然后在我的所有端点中,我都在捕获异常并使用此方法来回复一般错误。

希望有帮助。

问候

于 2012-11-21T15:57:04.297 回答
0

您可以使用 Guice 的AOP 优势来绑定方法拦截器以捕获异常并将其序列化到 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
     // ...        
}

参考:https ://code.google.com/p/google-guice/wiki/AOP

于 2013-06-20T08:41:31.327 回答