Пользовательская HTTP-фраза с использованием ExceptionMapper

Я определил следующее Exception Mapper для обработки пользовательских HttpCustomException

package com.myapp.apis;

import com.myapp.apis.model.HttpCustomException;
import com.myapp.apis.model.HttpCustomExceptionStatusType;
import com.myapp.apis.model.HttpCustomNotAuthorizedException;

import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;

@Provider
public class HttpCustomExceptionMapper implements ExceptionMapper <HttpCustomException> {

  @Override
  public Response toResponse (HttpCustomException e) {
    Response response = Response.status (new HttpCustomExceptionStatusType (Response.Status.UNAUTHORIZED, e.getMessage ())).build ();
    if (e instanceof HttpCustomNotAuthorizedException) {
      response = Response.status (new HttpCustomExceptionStatusType (Response.Status.INTERNAL_SERVER_ERROR, e.getMessage ())).build ();
    }

    System.out.println ("HttpCustomExceptionMapper: " + response.getStatus () + ", " + response.getStatusInfo ().getReasonPhrase ());
    return response;
  }
}

Когда HttpCustomNotAuthorizedException в коде, я вижу сообщение журнала, определенное в конце toResponse метод, в catalina.out. Итак, класс HttpCustomExceptionMapper вызывается во время обработки запроса. Но, в конечном ответе, я вижу в клиенте, я вижу только стандарт Not Authorized сообщение, а не пользовательское сообщение, которое я установил в ответе.

Почему это происходит?

2 ответа

Решение

Следует отметить, что текущая версия протокола HTTP (HTTP/2) вообще не поддерживает фразу причины. Он был удален из протокола.

Таким образом, поддержка отправки фразы причины была удалена из Tomcat 9.0 и выше. В Tomcat 7.0 поддержка 8.5 для отправки пользовательской фразы причины по умолчанию отключена (может быть включена с помощью системного свойства, org.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER). В 8.5 вы также должны установить sendReasonPhrase="true" на соединителе.

Это показывает стандартный ответ, потому что вы не устанавливаете тело для своего ответа, вы только устанавливаете статус. Вы должны передать пользовательский ответ, как это:

Response response = Response.status (Response.Status.INTERNAL_SERVER_ERROR).entity(CustomResponse).build ();

Я не в порядке с дизайном, но это будет что-то вроде:

HttpCustomExceptionStatusType  status = new HttpCustomExceptionStatusType (Response.Status.INTERNAL_SERVER_ERROR, e.getMessage ())
Response response = Response.status (status).entity(status).build ();
Другие вопросы по тегам