Я использую Spring 4.0.6 в приложении сервлета. У меня есть абстрактный базовый контроллер с некоторыми общими методами для всех моих контроллеров.
Одним из таких методов является редирект. Я хочу иметь метод с подписью
redirect(String path)
Чтобы отправить перенаправление, я использую
response.sendRedirect(response.encodeRedirectURL(path));
Поскольку я хотел бы, чтобы сигнатуры методов были короткими и чистыми, мне нужно получить доступ к объекту ответа внутри метода суперкласса.
Чтобы сделать это, я последовал предложению, найденному в Интернете, и определил фильтр сервлета с помощью ThreadLocal HttpServletResponse.
public class ResponseFilter extends OncePerRequestFilter {
private static final ThreadLocal<HttpServletResponse> responses = new ThreadLocal<HttpServletResponse>();
public static HttpServletResponse getResponse() {
return responses.get();
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
try {
responses.set(response);
} finally {
try {
filterChain.doFilter(request, response);
} finally {
responses.remove();
}
}
}
}
Поскольку я использую безопасность Spring с конфигурацией Java, я добавляю этот фильтр в свой подкласс WebSecurityConfigurerAdapter:
.addFilterAfter(rf, SwitchUserFilter.class)
Обратите внимание, что я также попытался добавить фильтр первым в цепочке фильтров и вместо этого попытался использовать Interceptor. Все с теми же результатами.
Я сравнил хэш-коды на объектах ответа, и, насколько я могу судить, хэш-коды совпадают, но перенаправление, похоже, игнорируется. Я также просмотрел идентификаторы объектов в точках останова в Eclipse, и снова у меня есть совпадение. Симптом заключается в том, что Spring DispatcherServlet входит в processDispatchResult и, кажется, думает, что ему нужно разрешить представление. Это представление не существует, так как я ожидаю перенаправления:
javax.servlet.ServletException: File "/WEB-INF/views/application/redirecttest.jsp" not found
Я заметил, что если я добавлю объект ответа обратно в сигнатуру метода контроллера сопоставления запросов, перенаправление суперкласса, похоже, работает (хотя я вообще не использую объект ответа метода контроллера).
К сожалению, такое поведение воспроизводится как на Mac, так и на Linux. Я использую Tomcat 7 в качестве контейнера.
ModelAndViewContainer.setRequestHandled()
, но я не понимаю, как вы можете получить к нему доступ за пределамиHandlerMethodArgumentResolver
(так это работает, когда вы добавляете объект ответа в подпись) илиHandlerMethodReturnValueHandler
. - person axtavt   schedule 26.07.2014