Ответ 1
Проблема заключается в том, что когда вы возвращаете имя вида из своего метода контроллера, Spring DispatcherServlet
выполняет пересылку вперед к данному виду, сохраняя исходный метод PUT
.
При попытке обработать этот форвард Tomcat откажется от этого, с обоснованием того, что a PUT
для JSP может быть истолковано как означающее "заменить этот JSP файл на сервере содержимым этого запроса".
Действительно, вы хотите, чтобы ваш контроллер обрабатывал ваши запросы PUT
, а затем впоследствии отправлял ваши JSP в качестве GET
. К счастью, Servlet 3.0 предоставляет средства для фильтрации только на диспетчере FORWARD
.
Создайте фильтр:
public class GetMethodConvertingFilter implements Filter {
@Override
public void init(FilterConfig config) throws ServletException {
// do nothing
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(wrapRequest((HttpServletRequest) request), response);
}
@Override
public void destroy() {
// do nothing
}
private static HttpServletRequestWrapper wrapRequest(HttpServletRequest request) {
return new HttpServletRequestWrapper(request) {
@Override
public String getMethod() {
return "GET";
}
};
}
}
И подключите его к своему web.xml
таким образом:
<filter>
<filter-name>getMethodConvertingFilter</filter-name>
<filter-class>my.GetMethodConvertingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>getMethodConvertingFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
Это преобразует запросы на GET
только в режиме forward, оставляя запросы через других диспетчеров без изменений, поэтому PUT
будет нормально перехватываться вашими контроллерами.
Мое (возможно неправильное) понимание заключается в том, что Tomcat 8.0.9 представил исправление, где это эффективно выполняется автоматически для диспетчера ERROR
- см. ответ в вашем связанный вопрос. Но вы не используете механизм обработки ошибок контейнера для рендеринга вашей страницы ошибки, вы используете Spring MVC для пересылки вручную в представление, поэтому вам нужно это сделать. Лично я столкнулся с этой проблемой в Jetty 9.2.7, где нет такого исправления, и я делегирую обработку ошибок в контейнер, поэтому у меня есть <dispatcher>ERROR</dispatcher>
, настроенный в моем отображении фильтра.
Все это кажется немного загадочным, но это единственный способ, с помощью которого я обнаружил, что успешно перешел через этот RESTful- Spring -JSP-web-приложение hoop.