目录
什么是拦截器
拦截器类似servlet中的过滤器,对页面请求判断和拦截,对控制器功能加强,在SpringMVC中实现HandlerInterceptor接口自定义拦截器
拦截器的执行流程
简单实例
控制器类
三个控制器转发到一个成功页面
@Controller
@RequestMapping("/inter")
public class showInter {
@RequestMapping("/inter1")
public String show1(){
return "success";
}
@RequestMapping("/inter2")
public String show2(){
return "success";
}
@RequestMapping("/inter3")
public String show3(){
return "success";
}
}
拦截器类
重写preHandle、postHandle、afterCompletion三个方法,分别会在不同时期调用。
public class Interceptor implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.print("前");
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.print("中");
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.print("后");
}
}
mvc.xml
SpringMVC的配置类中添加,告诉拦截器拦谁。并列写多个拦截器配置,可以多个拦截器拦一个,也可以一个拦截器拦多个
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/login"/>
<bean class="zs.interceptor.Myinter"></bean><!--执行拦截器类的Bean对象-->
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/inter/*"/>
<bean class="zs.interceptor.Interceptor"></bean>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/inter/inter1"/>
<bean class="zs.interceptor.Interceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
解决CSRF攻击
什么是CSRF
在访问正规网站后没有退出,然后访问流氓网站,流氓网站假装用户去访问用户在其他网站的账户内容,盗取信息,甚至消费转账
解决
利用用户正常访问和跨站请求伪造的区别进行拦截,用户正常请求经过登录页面,而伪请求不经过登录页面伪造登录。在前端页面中生成随机**通过请求的方式传到控制器,同时**保存到session,后台对比,这就保证必须经过指定页面才能访问部分受保护的内容
页面
<%
//安全随机数
SecureRandom random = new SecureRandom();
random.setSeed(1561);//随机种子
double rand = random.nextDouble();
session.setAttribute("rand", rand);
%>
<form action="/login" method="post">
用户名<input type="text" name="username">
密码<input type="password" name="password">
<input type="hidden" name="rand" value="${sessionScope.rand}">
<input type="submit" value="提交">
</form>
控制器
@RequestMapping("/login")
public String login(String name,String password){
return "success";
}
拦截器
preHandle方法中的
String rand;
String rand2=null;
rand=httpServletRequest.getParameter("rand");
if(httpServletRequest.getSession().getAttribute("rand")!=null)
rand2=httpServletRequest.getSession().getAttribute("rand").toString();
httpServletRequest.getSession().removeAttribute("rand");
if(rand!=null&&rand2!=null&&rand.equals(rand2)){
return true;
}else{
return false;
}
与过滤器的区别
过滤器
依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。
使用过滤器的目的是用来做一些过滤操作,过滤敏感文字等。
拦截器
依赖于web框架。在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。由于拦截器是基于web框架的调用,
因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。
但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理。