响应具有错误状态时为空主体 (Apache CXF)
Empty body when response has error status (Apache CXF)
假设有一个休息端点在 host.tld/api
上侦听并且 returns 一个 404 Not Found
具有以下正文:
{
"status": 404,
"message": "This is a custom error message",
"errorNr": 13400
}
另外还有一个 ClientResponseFilter,如下所示:
public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
if (responseContext.getStatus() != Response.Status.OK.getStatusCode()) {
// get the real error message
CustomExceptionData error = new ObjectMapper().readValue(
responseContext.getEntityStream(),
CustomExceptionData .class
);
throw new CustomException(error.getErrorNr(), error.getStatus(), error.getMessage());
}
}
客户端使用此代码检索其余端点的响应:
WebTarget target = getTarget();
try {
return target.request(MediaType.APPLICATION_JSON_TYPE).get(MyCustomDTO.class);
} catch (Exception e) {
if (e.getCause() instanceof CustomException) {
// some other logic
}
}
代码必须与球衣和 apache cxf JAX-RS 实现一起使用。现在看看最后一个代码块。使用球衣时,我得到一个 javax.ws.rs.ProcessingException
并执行 e.getCause()
returns 一个 CustomException
,所以一切都是正确的。使用 Apache CXF 时,我得到一个 javax.ws.rs.NotFoundException
,其中完全没有关于响应主体的信息以及 e.getCause()
returns null
的位置。为什么会有这样的差异?我该如何解决?
就在抛出异常之前,您可以将状态代码设置为 200,这将防止 CXF 抛出 NotFoundException
:
public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
if (responseContext.getStatus() != Response.Status.OK.getStatusCode()) {
// get the real error message
CustomExceptionData error = new ObjectMapper().readValue(
responseContext.getEntityStream(),
CustomExceptionData .class
);
responseContext.setStatus(Response.Status.OK.getStatusCode());
throw new CustomException(error.getErrorNr(), error.getStatus(), error.getMessage());
}
}
假设有一个休息端点在 host.tld/api
上侦听并且 returns 一个 404 Not Found
具有以下正文:
{
"status": 404,
"message": "This is a custom error message",
"errorNr": 13400
}
另外还有一个 ClientResponseFilter,如下所示:
public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
if (responseContext.getStatus() != Response.Status.OK.getStatusCode()) {
// get the real error message
CustomExceptionData error = new ObjectMapper().readValue(
responseContext.getEntityStream(),
CustomExceptionData .class
);
throw new CustomException(error.getErrorNr(), error.getStatus(), error.getMessage());
}
}
客户端使用此代码检索其余端点的响应:
WebTarget target = getTarget();
try {
return target.request(MediaType.APPLICATION_JSON_TYPE).get(MyCustomDTO.class);
} catch (Exception e) {
if (e.getCause() instanceof CustomException) {
// some other logic
}
}
代码必须与球衣和 apache cxf JAX-RS 实现一起使用。现在看看最后一个代码块。使用球衣时,我得到一个 javax.ws.rs.ProcessingException
并执行 e.getCause()
returns 一个 CustomException
,所以一切都是正确的。使用 Apache CXF 时,我得到一个 javax.ws.rs.NotFoundException
,其中完全没有关于响应主体的信息以及 e.getCause()
returns null
的位置。为什么会有这样的差异?我该如何解决?
就在抛出异常之前,您可以将状态代码设置为 200,这将防止 CXF 抛出 NotFoundException
:
public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
if (responseContext.getStatus() != Response.Status.OK.getStatusCode()) {
// get the real error message
CustomExceptionData error = new ObjectMapper().readValue(
responseContext.getEntityStream(),
CustomExceptionData .class
);
responseContext.setStatus(Response.Status.OK.getStatusCode());
throw new CustomException(error.getErrorNr(), error.getStatus(), error.getMessage());
}
}