看了一下午的文档,对Filter(过滤器)和Interceptor(拦截器)有了更深入的理解,下面主要记录对这两个在未登录时自动跳转登录页面的实现的一些自己的理解。
首先要求拦截未登录自动跳转登录页面这种场景,用Filter(过滤器)和Interceptor(拦截器)都能够实现。
但Filter(过滤器)和Interceptor(拦截器)有以下差异。
1、拦截器是基于java的反射机制的;而过滤器是基于函数回调 。
2、过滤器的实现与struts2、spring等框架无关,在用户请求被相应前执行,它依赖与servlet容器;而拦截器由Spring管理,不依赖与servlet容器,拦截器只对action起作用,不能拦截jsp页面、图片等其他资源。
3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用(比如jsp、html、js、css、图片等) 。
4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能 。
5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次 。
6、过滤器的配置在web.xml中,而拦截器的配置在基于使用的mvc框架不同在不同的xml配置中(如Strust2在strust.xml,而springmvc在spring-mvc.xml中)。
7、Filter是Servlet规范规定的,只能用于Web程序中。而拦截器既可以用于Web程序,也可以用于Application、Swing程序中。
8、拦截器是一个Spring的组件,归Spring管理,配置在Spring文件中,因此能使用Spring里的任何资源、对象,例如Service对象、数据源、事务管理等,通过IOC注入到拦截器即可;而Filter则不能。
9、Filter在只在Servlet前后起作用。而拦截器能够深入到方法前后、异常抛出前后等,因此拦截器的使用具有更大的弹性。
10、Filter根据mapping配置的先后顺序;Interceptor也是按照配置的顺序,但是可以通过order控制顺序。
其实用Filter和Interceptor都能实现拦截未登录自动跳转登录页,但是在实际我接触过的项目(主要是一些企业级开发的项目,用户量并不太大)中基本上使用的都是Filter。
注意:Interceptor是针对action的拦截,如果知道jsp地址的话在URL栏直接输入JSP的地址,那么拦截器是没有效果的,可以通过把所有的jsp放到WEB-INF下面避免。
下面是从网上摘的Filter(过滤器)和Interceptor(拦截器)实现拦截的案例
Filter过滤器实现
配置:web.xml
<filter>
<filter-name>RightFilter</filter-name>
<filter-class>com.***.rights.RightFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>RightFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>RightFilter</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
java代码:
mport 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.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class RightFilter extends HttpServlet implements Filter {
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) arg1;
HttpServletRequest request=(HttpServletRequest)arg0;
HttpSession session = request.getSession(true);
String usercode = (String) session.getAttribute("usercode");//
String url=request.getRequestURI();
if(usercode==null || usercode.equals(""))
{
//判断获取的路径不为空且不是访问登录页面或执行登录操作时跳转
if(url!=null && !url.equals("") && ( url.indexOf("Login")<0 && url.indexOf("login")<0 ))
{
response.sendRedirect("登录路径");
return ;
}
}
//已通过验证,用户访问继续
arg2.doFilter(arg0, arg1);
return;
}
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
Interceptor拦截器实现(struts框架):
ps:struts2通过继承AbstractInterceptor抽象类实现拦截器
配置:struts.xml
<interceptors>
<!--定义一个名为authority的拦截器-->
<interceptor class="com.***.rights.RightInterceptor" name="rightInterceptor"/>
<!--定义一个包含权限检查的拦截器栈-->
<interceptor-stack name="mydefault">
<!--配置内建默认拦截器-->
<interceptor-ref name="defaultStack"/>
<!--配置自定义的拦截器-->
<interceptor-ref name="rightInterceptor"/>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="mydefault" />
<!--定义全局Result-->
<global-results>
<result name="login">Login.jsp</result>
<result name="error">/error.jsp </result>
</global-results>
java代码:
import java.util.HashMap;
import java.util.Map;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.ActionContext;
public class RightInterceptor extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation invocation) throws Exception {
//System.out.println("拦截器开始验证");
try
{
ActionContext actionContext = ActionContext.getContext();
Map<String,Object> session = actionContext.getSession();
String user=session.get("usercode").toString();
//当前用户session无效且访问的action不是登录action时,执行拦截,跳转
if((user==null || user.equals("")) && !invocation.getAction().getClass().getName().equals("登录action"))
{
return Action.LOGIN;
}
}
catch(Exception e)
{
e.printStackTrace();
return Action.LOGIN;
}
//System.out.println("拦截器通过验证");
return invocation.invoke();//执行访问的action
}
}
Interceptor拦截器实现(springmvc框架):
ps:springmvc通过实现HandlerInterceptor接口实现拦截器
配置:spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 扫描controller(controller层注入) -->
<context:component-scan base-package="com.bybo.aca.web.controller"/>
<mvc:interceptors>
<mvc:interceptor>
<!-- 拦截所有URL中包含/user/的请求 -->
<mvc:mapping path="/user/**"/>
<!-- 不进行拦截 -->
<mvc:exclude-mapping path="/index.html"/>
<bean class="com.jikexueyuan.demo.springmvc.lesson4.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
<!-- 定义跳转的文件的前后缀 ,视图模式配置-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 自动给后面action的方法return的字符串加上前缀和后缀,变成一个 可用的url地址 -->
<property name="prefix" value="/WEB-INF/page/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
java代码:
package com.jikexueyuan.demo.springmvc.lesson4.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.jikexueyuan.demo.springmvc.lesson4.constant.Global;
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object user = request.getSession().getAttribute(Global.USER_SESSION_KEY);
if (user == null) {
System.out.println("尚未登录,调到登录页面");
response.sendRedirect("/loginpage.html");
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion");
}
}