Как изменить ответ на запрос HTTP OPTIONS в приложении Spring MVC 2.5? - PullRequest
3 голосов
/ 02 марта 2011

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

У меня есть приложение Spring MVC. Я не поддерживаю никакие методы http, кроме GET и POST. У меня есть следующий набор во всех моих компонентах контроллеров:

<property name="supportedMethods" value="GET,POST"/>

Однако запрос OPTIONS, отправленный моему приложению, возвращает ответ, который показывает все http методы как разрешенные.

Как изменить ответ OPTIONS, чтобы показывать только разрешенные методы GET и POST? Я знаю, что мог бы сделать это в сервлете, переопределив метод doOptions, но я не уверен насчет Spring MVC-приложения. Нужно ли расширять DispatcherServlet и переопределять doOptions?

Приложение использует Spring mvc 2.5.6 с контроллерами на основе SimpleFormController и конфигурацией на основе xml.

Ответы [ 3 ]

2 голосов
/ 02 марта 2011

Предупреждение: я не обработал сообщения OPTIONS.

В вашем обработчике запросов (аннотированном @Controller) вы можете использовать RequestMethod.OPTIONS для обработки запроса параметров. Например, вы можете использовать

  ... stuff ...  
  @RequestMapping(RequestMethod.OPTIONS)  
  public String processOptions()
  {
  ... stuff ...
  }
1 голос
/ 15 декабря 2011

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

Подход @RequestMapping (RequestMethod.OPTIONS) не будет работать сразу при использовании DispatcherServlet из коробки, поскольку его суперкласс FrameworkServlet сначала делегирует своему суперклассу HttpServlet, как отмечалось выше, который сканирует сервлет, чтобы увидеть, реализует ли он методы doXXX и соответственно устанавливают заголовок Allow. Но после вызова super.doOptions (...) он имеет следующие строки:

if (this.dispatchOptionsRequest) {
     processRequest(request, response);
}

И есть setDispatchOptionsRequest (логическое значение), которое можно использовать для установки значения dispatchOptionsRequest в значение true. Только тогда DispatcherServlet передаст в контроллер запрос OPTIONS соответствующему аннотированному методу.

Мне нужно было сделать это, чтобы запрос OPTIONS мог возвращать разные значения в зависимости от полномочий текущего пользователя. Таким образом, создав подкласс DispatcherServlet и установив этот параметр в его конструкторе по умолчанию, я наконец смог получить вызов в моем контроллере для запросов http OPTIONS и обработать его самостоятельно.

И еще одна мысль: в этом методе контроллера вы можете объявить параметр типа HttpServletResponse, и Spring передаст вам экземпляр. После этого вы можете вызвать reset (), чтобы очистить уже установленный заголовок Allow и при необходимости свернуть свой собственный.

(Примечание. Аналогичная схема имеется в FrameworkServlet для поддержки http TRACE через setDispatchTraceRequest, если вы планируете получать эти запросы через методы контроллера, аннотированные @RequestMapping (RequestMethod.TRACE)).

1 голос
/ 11 марта 2011

Я думаю, вы могли бы вызвать WebContentGenerator#setSupportedMethods, который получает в качестве входного параметра массив строк, содержащий поддерживаемые методы.WebContentGenerator - это базовый класс для контроллеров Spring 2.x, так что вам просто нужно вызвать этот метод во время создания вашего контроллера, который его обязательно расширяет.Вы также можете использовать конструктор WebContentGenerator, который получает строку varargs (поддерживаемые методы) в качестве входного параметра.

К сожалению, метод doOptions в классе FrameworkServlet вызывает super.doOptions(request, response); класса HttpServlet.Выход этого метода основан на объявленных методах в сервлете, что-то вроде этого:

Method[] methods = getAllDeclaredMethods(this.getClass());

for (int i = 0; i < methods.length; i++) {
    Method m = methods[i];

    if (m.getName().equals("doGet")) {
        ALLOW_GET = true;
        ALLOW_HEAD = true;
    }
    if (m.getName().equals("doPost"))
        ALLOW_POST = true;
    if (m.getName().equals("doPut"))
        ALLOW_PUT = true;
    if (m.getName().equals("doDelete"))
        ALLOW_DELETE = true;
}

Класс DispatcherServlet (и его базовый класс FrameworkServlet) объявляют все эти методы: doPut, doDeletedoGet, doPost и т. Д., Поэтому вывод doOptions - это не то, что вам нужно.Я думаю, что единственный способ - создать подкласс DispatcherServlet.

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