【发布时间】:2013-11-20 02:31:17
【问题描述】:
我有一个 RESTful Web 应用程序,它连接到数据库并具有正常的 REST、业务逻辑服务和持久层。在 RESTful 层中处理运行时错误(如数据库连接不可用)的 JAX-RS 标准方法是什么?我相信我在下面使用的方法,其中我使用 Throwable 的 try/catch 包装对我的服务/持久层的任何调用并抛出我的自定义 MyAppRuntimeException 有点尴尬。有什么建议吗?
RESTful 服务:
@Path("service")
@Consumes({"application/json"})
@Produces({"application/json"})
public class MyResource {
@GET
@Path("/{id}")
public Response getPage(@PathParam("id") long id){
Object test=null;
try {
test = ...
//call business logic service method here which makes a call to database and populates test instance
} catch (Throwable e) {
throw new MyAppRuntimeException("custom error message string");
}
if(test != null){
return Response.ok(test).build();
}else{
return Response.status(Status.NOT_FOUND).build();
}
}
}
自定义异常:
public class MyAppRuntimeException extends RuntimeException {
private static final long serialVersionUID = 1L;
public MyAppRuntimeException(String message) {
super(message);
}
public MyAppRuntimeException(String message, Throwable cause) {
super(message, cause);
}
}
异常 JAX-RS 响应映射器:
@Provider
public class MyAppRuntimeExceptionMapper implements ExceptionMapper<MyAppRuntimeException> {
private static final String ERROR_KEY = "DATA_ERROR";
@Override
public Response toResponse(MyAppRuntimeException exception) {
ErrorMessage errorMessage = new ErrorMessage(ERROR_KEY, exception.getMessage(), null);
return Response.status(Status.INTERNAL_SERVER_ERROR).entity(errorMessageDTO).build();
}
}
【问题讨论】:
-
您是否可以控制来自业务逻辑的异常?您可以直接映射这些异常,并避免可能隐藏代码(例如空指针异常)和性能(例如内存不足错误)的 catch Throwable。与说“服务不可用”相反,禁止也是对响应代码状态的适当描述吗?您的要求将决定这样,但需要考虑一些事情。 :)
-
默认情况下,我认为未捕获的异常应该会导致内部服务器错误,这也可以根据您的需求/您想与您的休息客户端定义的合同。
-
如果test = null,你也可以抛出WebApplicationException,从而允许你在OK的情况下只返回值test。
-
@Charlie - 我确实可以控制业务逻辑中可能发生的一些已知异常,这些异常是使用不同的异常和映射器类抛出和映射的。我想 Status.INTERNAL_SERVER_ERROR 比 Forbidden 或 service不可用更合适,因为 NullPointerException 并不意味着它不可用。
-
@c12 你为什么不声明自己的
ExceptionMapper处理通用Exception。然后只声明getPage(..) throws Exception并让mapper 处理抛出的异常?