Отсутствует тело в отрицательных ответах REST

#java #rest #httpresponse

#java #rest #httpresponse

Вопрос:

Я создал свои собственные классы REST и вызываю using curl -v "http://10.0.0.4:49152/rest/geo?loc=12345amp;get=description" (например). Я также вызываю их из java с помощью httpClient.send .

В обоих случаях, если класс REST возвращает строку, тогда все в порядке — тело сообщения содержит строку; но если мой класс REST вместо этого выдает исключение, возвращаемый объект / сообщение не содержит моего пользовательского сообщения:

 @GET 
@Produces("text/plain")
@Override
public String get(@Context UriInfo uriInfo, @Context Request request)
{
    String queryString = uriInfo.getRequestUri().getQuery();
    //etc
    if (somethingIsWrong)
    {
        // I don't see this message in the response
        throw new BadRequestException("GET request issue - something is wrong");
    }
    else
    {
        return correctString;
    }
}
  

Ответ — это код 400, чего я и ожидал, но это мой результат:

 *   Trying 10.0.0.4...
* TCP_NODELAY set
* Connected to 10.0.0.4 (10.0.0.4) port 49152 (#0)
> GET /rest/geo?loc=12345amp;get=description HTTP/1.1
> Host: 10.0.0.4:49152
> User-Agent: curl/7.55.1
> Accept: */*
>
< HTTP/1.1 400 Bad Request
< Date: Thu, 22 Oct 2020 14:20:37 GMT
< Content-length: 0
<
* Connection #0 to host 10.0.0.4 left intact
  

Аналогично, в сообщении java HttpResponse я вижу код (400), но не сообщение в моем исключении.

Как я могу увидеть возвращенное сообщение?

Ответ №1:

Вероятно, это проблема, связанная с конкретным контейнером. Чтобы решить такие проблемы раз и навсегда, я лично использую ExceptionMapper подобное:

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

@Provider
public class RestExceptionMapper implements ExceptionMapper<Throwable> {

    @Override
    public Response toResponse(Throwable t) {
        Object entity;
        Response.Status status;
        if (t instanceof SomeException) {
            status = // compute status
            entity = t.getMessage();
        } else {
            status = Response.Status.INTERNAL_SERVER_ERROR;
            entity = "Server error";
        }

        return Response
                .status(status)
                .type(MediaType.TEXT_PLAIN)
                .entity(entity)
                .build();
    }
}
  

Аннотированный @Provider аннотацией класс будет автоматически обнаружен контейнером.