Пустое тело, когда ответ имеет статус ошибки (Apache CXF) - PullRequest
1 голос
/ 16 апреля 2020

Представьте, что конечная точка покоя прослушивает host.tld/api и возвращает 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() возвращает CustomException, так что все правильно. При использовании Apache CXF я получаю javax.ws.rs.NotFoundException без какой-либо информации о теле ответа и о том, где e.getCause() возвращает null. Почему такая разница? И как я могу это исправить?

1 Ответ

1 голос
/ 19 апреля 2020

Непосредственно перед тем, как вы сгенерируете свое исключение, вы можете установить код состояния на 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());
        }
}
...