1. 核心代码
package util;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
//过滤器的拦截路径一般有这4种方式
/*
* 1.拦截所有资源:/*或/,访问所有的资源,过滤器都会被执行
2.具体资源路径:/myServlet/demo1,只有访问myServlet/demo1资源时,过滤器才会被执行
3.拦截目录:/myServlet/*,访问/myServlet下所有资源是,过滤器都会被执行
4.后缀名被拦截:*.jsp,访问后缀名为jsp资源时,过滤器都会被执行
注意:/stu/*.do 这种混合的写法是错误的
*/
@WebFilter(urlPatterns= {"/index.do","/stu/*","/bj/*"})
public class LoginFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request1 =(HttpServletRequest) request;
HttpServletResponse response1 =(HttpServletResponse) response;
HttpSession session =request1.getSession();
if(session.getAttribute("user")!=null) {//如果登录成功,session中就会有user
chain.doFilter(request1, response1);
}else{//如果登录失败,跳到登录页面
//System.out.println(request1.getContextPath());/* /testSpringMVC3 */
response1.sendRedirect(request1.getContextPath()+"/user/showLogin.do");//使用绝对路径:项目名+/user/showLogin.do
}
}
}
2. 代码分析
2.1 重定向使用相对定位
response1.sendRedirect("user/showLogin.do");
-
过滤器在index.do,可以正常重定向
测试路径:http:localhost:8080/项目名/index.do
重定向成功:http:localhost:8080/项目名/user/showLogin.do -
过滤器在stu或bj,可以正常重定向
测试路径:http:localhost:8080/项目名/bj
重定向成功:http:localhost:8080/项目名/user/showLogin.do -
过滤器在stu/xxx或bj/xxx,不会正常重定向
测试路径:http:localhost:8080/项目名/stu/
重定向失败:http:localhost:8080/项目名/stu/user/user/user/user/user/user/user/user/user/user/user/user/user/user/user/user/user/user/user/showLogin.do
2.1.1 失败的原因分析
因为user/showLogin.do会拼接到最后一个/后面,
即,拼接到http:localhost:8080/项目名/stu/ 后面
此时,重定向之后的路径为:http:localhost:8080/项目名/stu/user/showLogin.do
仍然满足过滤器的条件 /stu/*
从而,再次重定向,陷入死循环
2.2 重定向使用绝对路径
response1.sendRedirect("/user/showLogin.do");
- 过滤器在任意路径,可以正常重定向,但重定向的路径不对
测试路径:http:localhost:8080/项目名/stu/
重定向失败:http:localhost:8080/user/showLogin.do
没有项目名,所以,重定向失败
2.3 重定向使用项目名+绝对路径
response1.sendRedirect(request1.getContextPath()+"/user/showLogin.do");//使用绝对路径:项目名+/user/showLogin.do
- request1.getContextPath()获取当前项目名=》/testSpringMVC3
- 这样重定向之后,就能直接定位到:http:localhost:8080/项目名/user/showLogin.do