过滤器和拦截器
过滤器和拦截器的区别
- java过滤器能够对目标资源的请求和响应进行截取。过滤器的工作方式分为四种:
1 request过滤器
2 forward过滤器
3 include过滤器
4 error过滤器 - java里的拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行,同时也提供了一种可以提取action中可重用部分的方式。在AOP(Aspect-Oriented Programming)中拦截器用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。
- 拦截器只能对action 请求起作用;
而过滤器则可以对几乎所有的请求起作用 - 过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前;
过滤器的触发时机是容器后,servlet之前,所以过滤器的doFilter(ServletRequest request, ServletResponse response, FilterChain chain)的入参是ServletRequest ,而不是httpservletrequest。因为过滤器是在httpservlet之前。
配置拦截器interceptor(实现登录模块拦截:无法从登录模块不经过登录直接跳转其他页面)
-
新建一个interceptor包,与bean、dao等层并列,并在其中新建一个类Logininterceptor,如图所示:
-
在这个类中,继承HandlerInterceptor接口,并实现preHandle、postHandle、afterCompletion三个方法(可利用快捷键Alt+/快捷导入三个方法):
本次只实现了preHandle方法,在拦截点进行拦截;若存在用户则登录成功,不拦截,否则,拦截,使其重定向为登录界面。
//拦截器类
public class Logininterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//在拦截点进行拦截,如果返回true,则不执行拦截点后的操作(拦截成功)
//返回false,表示不拦截
HttpSession session = request.getSession();
//拦截点:项目发起的url
String url = request.getRequestURI();
//if (session.getAttribute("user") != null || url.indexOf("user/doLogin.do") != -1) {//indexof-路径在字符串内出现的下标
if (session.getAttribute("user") != null){
//登录成功
return true;//不拦截
} else {//拦截
response.sendRedirect(request.getContextPath() + "/user/doLogin.do");
return false;
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//处理过程中进行拦截
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//执行完毕,返回前拦截
}
}
- 在spring-mvc.xml中配置拦截器
①:
<mvc:mapping path="/**"/> 是已经拦截了所有请求,包括登录,如果后来想不拦截某个页面,就在拦截配置里面配置: <mvc:exclude-mapping path="/system/login" />
②:也可以不在配置文件里拦截某个页面请求,在拦截类里面获取拦截路径,然后做个判断
<!--4.配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!--拦截所有的mvc控制器-->
<mvc:mapping path="/**"/>
<!--另一种拦截方式,可以对某个请求设置不拦截,这里添加后,那么logininterceptor可以不进行对usrl的拦截-->
<mvc:exclude-mapping path="/user/doLogin.do"/>
<!--告诉用哪个拦截器进行拦截-->
<bean class="com.whut.interceptor.Logininterceptor">
</bean>
</mvc:interceptor>
</mvc:interceptors>
配置过滤器filter(实现拦截页面)
配置过拦截器发现:只能拦截请求,但在地址栏里直接转向其他页面,仍然可以成功。因此需要配置过滤器,实现页面拦截。
- 新建一个filter包,与bean、dao等层并列,并在其中新建一个类Loginfilter,如图所示:
- 在类中,继承Filter类,实现init、doFilter、destroy方法
public class Loginfilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//过滤器出生
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//ServletRequest是一个接口,HttpServletRequest是一个实现
//HttpServletRequest有些方法,ServletRequest中没有比如:getsession
HttpServletRequest request=(HttpServletRequest)servletRequest;
HttpServletResponse response=(HttpServletResponse)servletResponse;
HttpSession session = request.getSession();
if(session.getAttribute("user")==null&&request.getRequestURI().indexOf("/user/doLogin.do")==-1)
{
//当前并没有登录
response.sendRedirect(request.getContextPath()+"/user/doLogin.do");
}else {
//已经登录继续下一步操作
filterChain.doFilter(request,response);
}
}
@Override
public void destroy() {
//过滤器死亡
}
}
- 配置web.xml
<!--使用filter,实现登录-->
<filter>
<filter-name>SessionFilter</filter-name>
<!--确定用哪个-->
<filter-class>com.whut.filter.Loginfilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SessionFilter</filter-name>
<url-pattern>/pages/*</url-pattern>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
如上,过滤器和拦截器就配置完成了,可以实现登录的拦截页面和请求操作,可以进一步保证系统安全性。