我在servlet应用程序中使用Spring 4.0.6。我有一个抽象的基本控制器,其中包含一些通用方法供我的所有控制器使用。
其中一种方法是重定向。我想要一个带签名的方法
redirect(String path)
要发送重定向,我正在使用
response.sendRedirect(response.encodeRedirectURL(path));
由于我想保持方法签名简洁明了,我需要访问超类方法中的响应对象。
为了做到这一点,我遵循了在线发现的建议,并使用ThreadLocal HttpServletResponse定义了一个servlet过滤器。
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();
}
}
}
}
当我使用带有Java配置的Spring安全性时,我在我的WebSecurityConfigurerAdapter子类中添加了这个过滤器:
.addFilterAfter(rf, SwitchUserFilter.class)
请注意,我还尝试在过滤链中首先添加过滤器,并尝试使用Interceptor。都具有相同的结果。
我已经在响应对象上比较了哈希码,而且我可以说,哈希码匹配,但重定向似乎被忽略了。我还在Eclipse中查看了断点上的对象id,再次,我有一个匹配。症状是spring DispatcherServlet进入processDispatchResult并且似乎认为它需要解析视图。该视图不存在,因为我希望进行重定向:
javax.servlet.ServletException: File "/WEB-INF/views/application/redirecttest.jsp" not found
我注意到,如果我在请求映射控制器方法签名中添加响应对象,则超类重定向似乎有效(即使我根本不使用控制器方法响应对象)。
不幸的是,这种行为在Mac和Linux上都是可重现的。我使用Tomcat 7作为容器。
答案 0 :(得分:1)
您的过滤器应该可以正常工作,但您面临的问题是另一个问题。如果您正在使用视图(如示例中所示),则需要从控制器返回重定向视图以强制重定向;只是指示响应对象重定向将无法工作,因为Spring MVC基础结构将在响应返回到Servlet容器之前尝试执行其操作(即视图解析)。
例如,如果使用约定从控制器方法将视图名称作为String返回,则需要在控制器中执行以下操作:
@RequestMapping("/redirectTest")
public String redirectTest() {
return "redirect:http://www.example.com";
}