package cn.com.leadfar.cms.backend.view;
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.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LoginFilter implements Filter
{
private String filterPattern;
@Override
public void destroy()
{
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException
{
// TODO Auto-generated method stub
//ServletRequest 实际是HttpServletRequest
//将ServletRequest转换成HttpServletRequest
//否则有些功能用不了
//专门处理HTTP协议Servlet
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)resp;
//requestURI 获得经过该过滤器所有路径信息
String requestURI = request.getRequestURI();
System.out.println(requestURI);
//截取/CMS_BF/backend/login.jsp后半段
//backend/login.jsp部分
String page = requestURI.substring(request.getContextPath().length());
System.out.println(page);
//判断HTTP SESSION中是否有LOGIN_ADMIN
HttpSession session = request.getSession();
String loginAdmin = (String) session.getAttribute("LOGIN_ADMIN");
//login.jsp和LoginServlet不用重定向
//session内无值且过滤到页面不是login.jsp,则不返回
//判断session是否有值 session ==null 为假,说明session有值,可以访问后台页面
//为真,说明session无值,向下判断
//判断是否是login.jsp或LoginServlet
//!(page.equals("/backend/login.jsp") or page.equals(“/backend/loginServlet”))
//为真说明session无值,且又不是这两个页面则不让向下执行返回到登录页面
//否则说明是其中一个则向下执行
//如果这样过滤的话那么那些图片、js、css还是会被拦截到,并不向下执行
//判断这些文件的路径是否匹配配置文件中配置的正则表达式.*Servlet|.*\\.jsp
if(page.matches(filterPattern))
{
if(loginAdmin == null && !(page.equals("/backend/login.jsp") || page.equals("/backend/LoginServlet")))
{
//redirect到login.jsp
response.sendRedirect(request.getContextPath() + "/backend/login.jsp");
return;
}
}
//有可能循环重定向(死循环)
//访问/backend/login.jsp或/backend/main.jsp
//进入该过滤器,发现session没有值,
//重定向到login.jsp
//又请求一次、又进入该过滤器从来出现死循环情况。
//系统的控制流会继续向下
//否则就停滞不前,到这里就结束了
chain.doFilter(req, resp);
}
@Override
public void init(FilterConfig config) throws ServletException
{
// TODO Auto-generated method stub
//如果正则表达式转义字符有两个\\会变成\\\\ 所以在xml转义字符一个\足够
//.*Servlet|.*\.jsp
filterPattern = config.getInitParameter("filterPattern");
}
}
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>cn.com.leadfar.cms.backend.view.LoginFilter</filter-class>
<init-param>
<param-name>filterPattern</param-name>
<!-- 正则表达式过滤 -->
<!-- .代表不管有多少字母 -->
<!-- 凡事以Servlet或.jsp结尾的都过滤 -->
<param-value>.*Servlet|.*\.jsp</param-value>
</init-param>
</filter>
<filter-mapping>
<!-- 过滤所有backend目录下的资源 -->
<!-- 如果前面有/不能用 /backend/*.jsp-->
<!-- 否则可以用*.jsp 过滤所有以jsp结尾的文件 -->
<filter-name>LoginFilter</filter-name>
<url-pattern>/backend/*</url-pattern>
</filter-mapping>
定义一个LoginFilter ,并配置它匹配/backend/*,即在/backend/下面的所有请求,均经过这个LoginFilter
url-pattern的定义只有三种形式:
1、精确匹配
如:
/backend/main.jsp
/backend/left.jsp
/backend/ArticleServlet
等等
2、目录匹配
如
/backend/*
3、扩展名匹配
如
*.jsp
url-pattern不支持以下方式,如:
/backend/*.jsp
使用这个表达式的意图是匹配/backend/下面的所有jsp,url-pattern不支持