如何在Servlet过滤器中进行重定向?

59

我正在尝试找到一种方法,将我的请求从过滤器重定向到登录页面,但我不知道如何从servlet进行重定向。我已经搜索过了,但我发现的是sendRedirect()方法,但我在过滤器中的响应对象上找不到该方法。这是什么原因?我该如何解决?

6个回答

87

在过滤器中,响应类型为ServletResponse而不是HttpServletResponse。因此需要强制转换为HttpServletResponse

HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.sendRedirect("/login.jsp");
如果使用上下文路径:
httpResponse.sendRedirect(req.getContextPath() + "/login.jsp");

还别忘了在结尾处调用return;


有没有办法在过滤器内部使用视图解析器来解决JSP路径? - FelipeKunzler
只有当请求来自浏览器时,它才能工作。这是外部重定向。 - Vahe Gharibyan
如果使用sendredirec,则会丢失conversationContext参数,那么我该如何重定向并保留conversationContext参数呢? - luis alberto juarez

13

我正在尝试找到一种方法将我的请求从过滤器重定向到登录页面

请勿

只需调用

chain.doFilter(request, response);

从过滤器中进行操作并使正常流程继续。

我不知道如何从servlet重定向

你可以使用

response.sendRedirect(url);

从servlet重定向


15
如果用户未登录,中止请求可以很有用。 - BalusC
response is of type ServletResponse and it should be casted to HttpServletResponse.Example : HttpServletResponse resp = (HttpServletResponse) response; resp.sendRedirect("templateName || pathName"); - Andrius
2
你为什么告诉他不要从过滤器重定向到身份验证页面?请详细说明原因? - Joe C
这完全没有回答问题。 - Vsevolod Golovanov
有两个问题没有解决:1.打破过滤器和servlet的链接;2.中止在此之前链接的过滤器的进一步处理(没有保证这是第一个)。请注意,在chain.doFilter之前和之后可能会进行编码。 - YoYo

10
如果您想要保留哈希和获取参数,您可以像这样做(在过滤器初始化时填充redirectMap):
String uri = request.getRequestURI();

String[] uriParts = uri.split("[#?]");
String path = uriParts[0];
String rest = uri.substring(uriParts[0].length());

if(redirectMap.containsKey(path)) {
    response.sendRedirect(redirectMap.get(path) + rest);
} else {
    chain.doFilter(request, response);
}

1
据我所知,浏览器不会将URI中“#”后面的任何内容发送到后端。那么,它应该如何工作? - Raj
你说得对。但是我记得服务器上的哈希值导致了错误。也许是因为我使用了curl或一些rest客户端。无论如何,拥有它来确保100%正确是很便宜的。 - user1079877

3
为什么要使用response对象?它是一个ServletResponse对象,它不提供sendRedirect()方法。相反,使用ServletRequest的request对象来转发请求。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // TODO Auto-generated method stub
        // place your code here

        request.getRequestDispatcher("login.html").forward(request,response);
        return;
        
    }

请查看javadoc文档


2

尝试并检查您的ServletResponse response是否是HttpServletResponse的实例,如下所示:

if (response instanceof HttpServletResponse) {
    response.sendRedirect(....);
}

过滤器方法的过滤器方法是 public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { - To Kra
1
@ToKra 这不是方法签名,会导致编译器错误。 - Kevin Workman

1

您的响应对象被声明为ServletResponse。要使用sendRedirect()方法,您需要将其转换为HttpServletResponse。这是一个扩展接口,添加了与HTTP协议相关的方法。


过滤器方法已经有了以下内容: public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { - To Kra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接