JAXRS客户机可以抛出自定义异常类型吗?
我希望我的服务客户机的消费者能够获得比标准JAX-RS WebApplicationException更有意义的异常,这样他们就可以根据异常的原因进行重试或不重试等操作
我在服务端有一个ExceptionMapper,它将实际异常作为返回异常中响应的实体,如下所示:
public Response toResponse(InternalException ex) {
return Response.status(ex.getStatus)
.entity(ex)
.type(MediaType.APPLICATION_JSON_TYPE)
.build();
}
这似乎有效。问题是,在客户机中,即使我有一个ClientResponseFilter从响应中提取并抛出InternalException,JAX-RS也会将其包装在ProcessingException中,这违背了本文的全部要点
Testcase: badRequest_clientCall_modeledExceptionThrown took 0.272 sec
Caused an ERROR
Unexpected exception, expected<not.actual.package.InternalException> but was<javax.ws.rs.ProcessingException>
java.lang.Exception: Unexpected exception, expected<not.actual.package.InternalException> but was<javax.ws.rs.ProcessingException>
Caused by: javax.ws.rs.ProcessingException
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:263)
at org.glassfish.jersey.client.JerseyInvocation$3.call(JerseyInvocation.java:709)
<Incredibly secret stuff ommitted>
Caused by: not.actual.package.InternalException
除了将最终输出包装成try/catch(我不喜欢这样做,因为这会使重试逻辑复杂化)之外,我实际上如何让这个客户机抛出正确的异常
# 1 楼答案
您可以使用spring或JavaEE的AOP(JaveEE APO example)。使用
@AroundInvoke
调用您的服务方法。只需在您的服务方法中抛出异常。我建议您创建自己的异常,如UsernameInvalidException
、ParameterErrorException
以下是JavaEE的代码示例:定义您的例外情况:
您的用户名InvalideExcepton:
定义您自己的ExceptionHandler,它是一个注释(请参阅此处的custom annotation):
定义一个异常抛出工厂(此工厂不是必需的,它只是用来抛出新的不同异常。需要抛出新异常时,您可以使用它。):
如何使用它? 在服务方法中,使用注释:
然后对于客户端,它将获得您的错误代码和错误消息
以上所有代码都是针对JavaEE的,如果您使用spring,您将找到相应的注释和技术