Джерси: возвращая ошибку 400 вместо 500, если дано неверное тело запроса - PullRequest
21 голосов
/ 23 марта 2012

Я использую встроенную в Джерси обработку Джексона для преобразования входящего JSON в POJO, например:

@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response newCustomer( CustomerRepresentation customer)
{
...
}

Если клиент отправляет JSON с недопустимыми полями, Джерси в настоящее время возвращает 500 Internal Server Error.Вместо этого я хотел бы вернуть 400 Bad Request, предпочтительно с какой-либо значимой детализацией, указывающей, в каких полях есть ошибки.

Любое понимание того, как это можно сделать?(По крайней мере, возвращать универсальный 400 вместо совершенно неподходящего 500?)

Обновление: Вот исключение, генерируемое на стороне сервера, прежде чем мой обработчик будет вызван:

javax.servlet.ServletException: org.codehaus.jackson.map.exc.UnrecognizedPropertyException: 
Unrecognized field "this_isnt_a_known"_field" (Class com.redacted....), not marked as ignorable

Ответы [ 4 ]

19 голосов
/ 24 мая 2012

Я наконец-то смог обойти эту проблему, реализовав ExceptionMapper, чтобы поймать UnrecognizedPropertyException, брошенный Джексоном, и сопоставить его с ответом 400 Bad Request:

@Provider
public class UnrecognizedPropertyExceptionMapper implements ExceptionMapper<UnrecognizedPropertyException>
{

    @Override
    public Response toResponse(UnrecognizedPropertyException exception)
    {
        return Response
                .status(Response.Status.BAD_REQUEST)
                .entity( "'" + exception.getUnrecognizedPropertyName() + "' is an unrecognized field.")
                .type( MediaType.TEXT_PLAIN)
                .build();
    }

}
3 голосов
/ 03 августа 2016

На земле dropwizard есть ExceptionMapper, называемый JsonProcessingExceptionMapper , который имеет схожую функциональность с тем, что вы ищете. Может быть, вы можете использовать это для вдохновения в том, как решить вашу конкретную проблему в мире без дроп-волшебников.

3 голосов
/ 04 марта 2016

Я попытался сопоставить статус 500 с статусом 400 с ответом HolySamosa, но исключение не было обнаружено этим картографом, и статус 500 все еще возвращался.

После отладки я обнаружил, что JsonParseException генерируется, а не UnrecognizedPropertyException . Это потому, что я отправлял какой-то мусорный текст (это был вовсе не JSON).

Когда я отправил правильный JSON со стороны клиента с форматом, который не подходил для моего DTO на стороне сервера, я получил UnrecognizedPropertyException . Таким образом, есть два случая для этого:

  • при отправке мусора, который не является JSON и
  • когда вы отправляете JSON, но это не соответствует вашему классу DTO.

Теперь я возвращаю статус 400 для обоих.

1 голос
/ 28 марта 2012

У меня была такая же проблема ... К сожалению, я не знаю хорошего способа перехватить исключение Джексона и сгенерировать ваш собственный код ошибки.

Один из вариантов - использовать @JsonIgnoreProperties, а затем строго проверять десериализованный объект. Это не скажет вам, передал ли ваш отправитель нежелательную информацию, но если он пропустил обязательные поля, вы поймете это.

Я не могу найти какой-либо способ доступа к фактическому переданному JSON, кроме создания класса @Provider для перехвата JSON, проверки его, а затем передачи его Джексону для десериализации.

...