鉴于以下POJO:
public class BaseEntity {
public Long id;
// ctor, getter & setter
}
public class Widget extends BaseEntity {
public String fizz;
public Boolean isBuzz;
// ctor, getters & setters
}针对远程REST服务,我有以下用于CRUDding Widget实例的客户端API:
public class WidgetServiceClient {
public void createWidget(Widget w) {
// RESTful call: POST localhost/widgets
}
public Widget getWidgetById(Long id) {
// RESTful call: GET localhost/widgets/{id}
}
}并公开了以下RESTful服务端点:
public class WidgetService {
// Web server passes POST localhost/widgets/ calls to this method.
public Widget createWidget(Widget w) {
// Create the 'w' widget in the DB and return it with its DB-generated ID.
}
// Web server passes GET localhost/widgets/{id} calls to this method.
public Widget getWidgetById(Long id) {
// Ask the DB for the Widget with the passed-in 'id'. If it exist return it.
// Otherwise return NULL.
}
}让我们假设我已经弄明白了将Widget实例序列化/反序列化到JSON /从JSON到JSON的“魔力”。
这个设计很棒,除非有一个服务器端的Exception,我想要与客户端RESTfully进行通信。
我的第一个倾向是修改BaseEntity,使其具有一个可用于将服务器端错误传递回客户端的Throwable:
public class BaseEntity {
public Long id;
public Throwable error;
// ctor, getters & setters
}因此:
public class WidgetService {
// Web server passes POST localhost/widgets/ calls to this method.
public Widget createWidget(Widget w) {
try {
// Create the 'w' widget in the DB and return it with its DB-generated ID.
} catch(Throwable t) {
w.setError(t);
}
return w;
}
// Web server passes GET localhost/widgets/{id} calls to this method.
public Widget getWidgetById(Long id) {
Widget w = new Widget();
try {
// Ask the DB for the Widget with the passed-in 'id'. If it exist return it.
// Otherwise return NULL.
} catch(Throwable t) {
w.setError(t);
}
return w;
}
}但是这感觉很混乱,我想知道Javaland的其他居民是否已经找到了解决这个问题的更好的方法/策略。我碰巧使用泽西-杰克逊进行REST/序列化,但我认为解决方案应该是框架无关的。
当服务返回NULL时,它也没有帮助,这是可能发生的。
因此,我问:如何在客户机和服务器之间来回传递Widget 实例( RESTfully ),但仍然允许服务器返回NULL和 Exceptions**/**Throwables**?**。
发布于 2014-10-28 05:32:39
我建议保持模型响应和错误响应分离--关注点分离。假设泽西岛知道如何从您的WebApplicationExceptions中吸取响应,允许您在错误响应中提供丰富的错误信息,从而帮助客户了解错误所在。
作为一个简单的例子,您可以将签名保留为返回Widget,并将WebApplicationException派生类抛出。您的客户端将在成功时收到一个200 Widget,在异常时收到404响应(例如,下面)。
// Web server passes GET localhost/widgets/{id} calls to this method.
public Widget getWidgetById(Long id) {
Widget w = new Widget();
try {
// Ask the DB for the Widget with the passed-in 'id'. If it exist return it.
// Otherwise return NULL.
} catch(NotFoundException e) {
throw new NotFoundException(Response.status(Response.Status.NOT_FOUND)
.entity("Widget " + id + " not found.").build());
} catch(Exception e) {
throw new WebApplicationException(Response
.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity("I don't know what happened, but trying again won't help: "
+ e.getMessage())
.build());
}
return w;
}注意:只有响应才会返回给客户端,除非您定义了自定义的ExceptionMapper。
注意:如果您独立地处理特定的异常,而不是捕捉Throwable,您的代码将更具可读性。上面,我将每个java异常映射到一个通用泽西内部服务器错误。
发布于 2014-10-27 20:12:35
我认为您可能需要使用Jaxrs机制@Provider:JAX-RS jersey ExceptionMappers User-Defined Exception
@Provider
public class UserNotFoundMapper implements
ExceptionMapper<UserNotFoundException> {
@Override
public Response toResponse(UserNotFoundException ex) {
return Response.status(404).entity(ex.getMessage()).type("text/plain")
.build();
}
}https://stackoverflow.com/questions/26595887
复制相似问题