Почему Spring Web генерирует ответ с кодом ошибки 415 на запрос GET? - PullRequest
0 голосов
/ 06 сентября 2018

Я преобразую приложение Spring из гораздо более старой версии Spring в текущую версию. Я столкнулся с рядом проблем, с которыми мне пришлось столкнуться. Вот тот, который я не понимаю, как делать исправления, и удивляюсь, почему я должен. Этот мне кажется ошибкой ...

У меня есть серия REST API, каждая из которых состоит из смеси запросов GET и POST. В случае тел запросов POST и во всех случаях тел ответов я возвращаю JSON. Следовательно, кажется, что я могу глобально определить свои типы возвращаемых данных для всего модуля API следующим образом:

@RequestMapping(path = "/api/v1", consumes = "application/json", produces = "application/json")
public class ApiService_Account extends ApiServiceBase {
    ...

Моя проблема в том, что я получаю ответ 415 на запросы GET с сообщением «Тип содержимого» не поддерживается ». Но GET-запросы, как правило, не имеют содержимого и, следовательно, не имеют типа содержимого. Почему код жалуется на тип несуществующего контента в случае, когда контент не ожидается?

Вот мое определение одной такой конечной точки, на случай, если это имеет значение:

@RequestMapping(method=RequestMethod.GET, value="/accounts")
@ResponseBody
public void getAccounts(...

Я не вижу смысла требовать заголовок Content-Type (и, возможно, конкретно JSON-тип) в запросе GET. Я бы предпочел не определять свои типы полезной нагрузки для каждого определения конечной точки.

Какой лучший курс здесь? Я что-то пропустил? Это ошибка? Есть ли способ указать свойство «потребляет» только для всех запросов POST?

ОБНОВЛЕНИЕ: Я вижу, что Spring здесь очень буквальный, и это, возможно, конец. Я говорю, что все мои конечные точки должны ожидать JSON, и он просто выполняет это. Возможно, не имеет смысла делать исключение для запросов GET, даже если в GET не должно быть тел. Так что, возможно, это «особенность». Тем не менее, я хотел бы знать, как обойти это, так что мне не нужно указывать «потребляет» на каждой из моих конечных точек. Я полагаю, что я мог бы поместить свои POST в один класс, а мои GET в другой. Тьфу.

PS: Если я уберу параметр «расходует» из первой аннотации, проблема исчезнет. Я еще не исследовал, ломает ли это мои методы POST, которые ожидают тела JSON.

1 Ответ

0 голосов
/ 07 сентября 2018

Определение @RequestMapping(consumes = "application/json") на уровне класса заставляет использовать заголовок Content-Type для всех запросов к одной из конечных точек, определенных в этом классе. В результате получается ответ 415, когда заголовок не указан.

Spring недостаточно умен, чтобы понять, что Content-Type в запросе GET не имеет смысла.

AFAIK, нет простого способа обойти это. Самое простое решение:

@RequestMapping(path = "/api/v1", produces = "application/json")
public class ApiService_Account extends ApiServiceBase {

    @RequestMapping(method=RequestMethod.GET, value="/accounts")
    @ResponseBody
    public void getAccounts(...

    @RequestMapping(method=RequestMethod.POST, value="/accounts", consumes = "application/json")
    public void saveAccount(@RequestBody Account account...

Таким образом, вам нужно будет определить consumes на RequestMapping конечной точке, которая действительно потребляет контент.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...