springmvc----拦截器
点滴记载,点滴进步,愿自己更上一层楼。
springmvc的拦截器,只需要实现HandlerInterceptor接口即可,里面有三个方法需要注意。
public interface HandlerInterceptor {
boolean preHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;
void postHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3, ModelAndView var4) throws Exception;
void afterCompletion(HttpServletRequest var1, HttpServletResponse var2, Object var3, Exception var4) throws Exception;
}
以上为源码。其中
preHandle 为action之前会执行,所以拦截器的逻辑写在这里面。用于处理各种的需要拦截的操作,比如session检查,登录验证,权限等等。
返回值为boolean,如果当前拦截器返回了个false表示拦截,则在它之后的拦截器就不再执行了。
postHandle 为执行完action方法后,返回ModelAndView后执行,可以在这里将一些公用模型数据传入。
afterCompletion 为所有方法执行完毕后执行,可以统一处理某些异常,日志等等。
下面开始实现。
首先定义一个自己的拦截器。
package com.soft.intercepter;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Created by xuweiwei on 2017/8/21.
*/
public class MyIntercepter01 implements HandlerInterceptor {
/**
* action之前会执行,所以拦截器的逻辑写在这里面。用于处理各种的需要拦截的操作,比如session检查,登录验证,权限等等。
* 返回值为boolean,如果当前拦截器返回了个false表示拦截,则在它之后的拦截器就不再执行了。
*/
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println(" preHandle start ...... ");
String name=httpServletRequest.getParameter("name");
String password = httpServletRequest.getParameter("password");
// 一个简单的拦截器实现,如果输入的用户名,密码符合要求,则可以执行请求 返回true,否则不执行 返回true
if("tom".equals(name)&&"123456".equals(password)){
System.out.println(" login pass 执行登录...... ");
return true;
}
System.out.println(" login fail 不执行登录操作 ...... ");
return false;
}
/**
* 执行完action方法后,返回ModelAndView后执行,可以在这里将一些公用模型数据传入。
*/
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println(" postHandle start ...... ");
}
/**
* 所有方法执行完毕后执行,可以统一处理某些异常,日志等等
*/
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println(" afterCompletion start ...... ");
}
}
写一个controller 定义一个urlmapping 用于测试
package com.soft.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
/**
* Created by xuweiwei on 2017/8/21.
*/
@Controller
@RequestMapping(value="/login")
public class TestIntercepterController {
/**
* 测试拦截器用
* @return ModelAndView
*/
@RequestMapping(value="/userLogin")
public ModelAndView testIntercepter(){
System.out.println(" testIntercepter start ...... ");
ModelAndView model = new ModelAndView();
model.setViewName("test/testJsonParam");
return model;
}
}
配置拦截器到springmvc.xml
<!-- 配置拦截器 -->
<mvc:interceptors>
<!-- 配置自己定义的拦截器 可以配置多个 -->
<mvc:interceptor>
<!-- 配置拦截路径,即 什么样的请求才会进入该拦截器。
如果配置成 /** 则表示拦截所有操作,相当于全局拦截器 -->
<mvc:mapping path="/login/*"/>
<!-- 注入自己定义的拦截器 -->
<bean class="com.soft.intercepter.MyIntercepter01"></bean>
</mvc:interceptor>
</mvc:interceptors>
这个配置只是拦截特定的请求,如果请求中没有login 则不拦截。
测试,
浏览器输入 http://localhost:8080/login/userLogin 回车
控制台打印结果,因为没有用户名密码,登录校验通不过,所以不进行某些操作
浏览器输入 http://localhost:8080/login/userLogin?name=tom&password=123456 回车
控制台打印结果,用户名密码正确,执行用户请求。
再测试以前的一个请求。对应代码
package com.soft.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
/**
* Created by xuweiwei on 2017/8/19.
*/
@Controller
public class TestController {
@RequestMapping(value = "/helloWorld")
public ModelAndView helloWorld(){
System.out.println(" helloWorld start ...... ");
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("msg","hello world!!!!!!!");
modelAndView.setViewName("test/helloworld");
return modelAndView;
}
}
浏览器输入 http://localhost:8080/helloWorld 这里另一个请求,该请求不拦截。
结果。
可以看出拦截器并没有执行。
简单的一个拦截器就这些内容。
但是项目中不会只用到一个拦截器。但是多个拦截器也就是重复上面的步骤而已,需要注意的是,判断什么时候拦截操作,什么时候放行。
下面测试多个拦截器的执行顺序。
首先定义多个拦截器。其中拦截器06的preHandle不放行,拦截操作。
package com.soft.intercepter;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Created by xuweiwei on 2017/8/21.
*/
public class MyIntercepter02 implements HandlerInterceptor {
/**
* action之前会执行,所以拦截器的逻辑写在这里面。用于处理各种的需要拦截的操作,比如session检查,登录验证,权限等等。
* 返回值为boolean,如果当前拦截器返回了个false表示拦截,则在它之后的拦截器就不再执行了。
*/
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("MyIntercepter02 preHandle start ...... ");
return true;
}
/**
* 执行完action方法后,返回ModelAndView后执行,可以在这里将一些公用模型数据传入。
*/
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("MyIntercepter02 postHandle start ...... ");
}
/**
* 所有方法执行完毕后执行,可以统一处理某些异常,日志等等
*/
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("MyIntercepter02 afterCompletion start ...... ");
}
}
package com.soft.intercepter;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Created by xuweiwei on 2017/8/21.
*/
public class MyIntercepter03 implements HandlerInterceptor {
/**
* action之前会执行,所以拦截器的逻辑写在这里面。用于处理各种的需要拦截的操作,比如session检查,登录验证,权限等等。
* 返回值为boolean,如果当前拦截器返回了个false表示拦截,则在它之后的拦截器就不再执行了。
*/
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("MyIntercepter03 preHandle start ...... ");
return true;
}
/**
* 执行完action方法后,返回ModelAndView后执行,可以在这里将一些公用模型数据传入。
*/
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("MyIntercepter03 postHandle start ...... ");
}
/**
* 所有方法执行完毕后执行,可以统一处理某些异常,日志等等
*/
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("MyIntercepter03 afterCompletion start ...... ");
}
}
package com.soft.intercepter;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Created by xuweiwei on 2017/8/21.
*/
public class MyIntercepter04 implements HandlerInterceptor {
/**
* action之前会执行,所以拦截器的逻辑写在这里面。用于处理各种的需要拦截的操作,比如session检查,登录验证,权限等等。
* 返回值为boolean,如果当前拦截器返回了个false表示拦截,则在它之后的拦截器就不再执行了。
*/
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("MyIntercepter04 preHandle start ...... ");
return true;
}
/**
* 执行完action方法后,返回ModelAndView后执行,可以在这里将一些公用模型数据传入。
*/
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("MyIntercepter04 postHandle start ...... ");
}
/**
* 所有方法执行完毕后执行,可以统一处理某些异常,日志等等
*/
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("MyIntercepter04 afterCompletion start ...... ");
}
}
package com.soft.intercepter;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Created by xuweiwei on 2017/8/21.
*/
public class MyIntercepter05 implements HandlerInterceptor {
/**
* action之前会执行,所以拦截器的逻辑写在这里面。用于处理各种的需要拦截的操作,比如session检查,登录验证,权限等等。
* 返回值为boolean,如果当前拦截器返回了个false表示拦截,则在它之后的拦截器就不再执行了。
*/
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("MyIntercepter05 preHandle start ...... ");
return true;
}
/**
* 执行完action方法后,返回ModelAndView后执行,可以在这里将一些公用模型数据传入。
*/
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("MyIntercepter05 postHandle start ...... ");
}
/**
* 所有方法执行完毕后执行,可以统一处理某些异常,日志等等
*/
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("MyIntercepter05 afterCompletion start ...... ");
}
}
package com.soft.intercepter;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Created by xuweiwei on 2017/8/21.
*/
public class MyIntercepter06 implements HandlerInterceptor {
/**
* action之前会执行,所以拦截器的逻辑写在这里面。用于处理各种的需要拦截的操作,比如session检查,登录验证,权限等等。
* 返回值为boolean,如果当前拦截器返回了个false表示拦截,则在它之后的拦截器就不再执行了。
*/
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("MyIntercepter06 preHandle start ...... ");
return false;
}
/**
* 执行完action方法后,返回ModelAndView后执行,可以在这里将一些公用模型数据传入。
*/
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("MyIntercepter06 postHandle start ...... ");
}
/**
* 所有方法执行完毕后执行,可以统一处理某些异常,日志等等
*/
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("MyIntercepter06 afterCompletion start ...... ");
}
}
springmvc.xml中的配置拦截器,将这几个拦截器都配置成全局的,拦截所有请求,看执行顺序。拦截器那个配置在前先加载哪个。
所以这里的加载顺序为01 02 03 04 05 06 。
<!-- 配置拦截器 -->
<mvc:interceptors>
<!-- 配置自己定义的拦截器 可以配置多个 -->
<mvc:interceptor>
<!-- 配置成 /** 则表示拦截所有操作,相当于全局拦截器 -->
<mvc:mapping path="/login/*"/>
<!-- 注入自己定义的拦截器 -->
<bean class="com.soft.intercepter.MyIntercepter01"></bean>
</mvc:interceptor>
<!-- 配置自己定义的拦截器 可以配置多个 -->
<mvc:interceptor>
<!-- 配置成 /** 则表示拦截所有操作,相当于全局拦截器 -->
<mvc:mapping path="/**"/>
<!-- 注入自己定义的拦截器 -->
<bean class="com.soft.intercepter.MyIntercepter02"></bean>
</mvc:interceptor>
<!-- 配置自己定义的拦截器 可以配置多个 -->
<mvc:interceptor>
<!-- 配置成 /** 则表示拦截所有操作,相当于全局拦截器 -->
<mvc:mapping path="/**"/>
<!-- 注入自己定义的拦截器 -->
<bean class="com.soft.intercepter.MyIntercepter03"></bean>
</mvc:interceptor>
<!-- 配置自己定义的拦截器 可以配置多个 -->
<mvc:interceptor>
<!-- 配置成 /** 则表示拦截所有操作,相当于全局拦截器 -->
<mvc:mapping path="/**"/>
<!-- 注入自己定义的拦截器 -->
<bean class="com.soft.intercepter.MyIntercepter04"></bean>
</mvc:interceptor>
<!-- 配置自己定义的拦截器 可以配置多个 -->
<mvc:interceptor>
<!-- 配置成 /** 则表示拦截所有操作,相当于全局拦截器 -->
<mvc:mapping path="/**"/>
<!-- 注入自己定义的拦截器 -->
<bean class="com.soft.intercepter.MyIntercepter05"/>
</mvc:interceptor>
<!-- 配置自己定义的拦截器 可以配置多个 -->
<mvc:interceptor>
<!-- 配置成 /** 则表示拦截所有操作,相当于全局拦截器 -->
<mvc:mapping path="/**"/>
<!-- 注入自己定义的拦截器 -->
<bean class="com.soft.intercepter.MyIntercepter06"></bean>
</mvc:interceptor>
</mvc:interceptors>
浏览器请求:http://localhost:8080/helloWorld控制台打印结果。
因为06拦截器不放行,
所以helloWorld action没有执行。
注意打印结果的顺序,preHandle先顺序打印,afterCompletion倒叙打印,并且postHandle没有执行,并且06的afterCompletion没有执行。
接下类将06放行,05不放行。
05拦截器
/**
* action之前会执行,所以拦截器的逻辑写在这里面。用于处理各种的需要拦截的操作,比如session检查,登录验证,权限等等。
* 返回值为boolean,如果当前拦截器返回了个false表示拦截,则在它之后的拦截器就不再执行了。
*/
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("MyIntercepter05 preHandle start ...... ");
return false;
}
06拦截器
/**
* action之前会执行,所以拦截器的逻辑写在这里面。用于处理各种的需要拦截的操作,比如session检查,登录验证,权限等等。
* 返回值为boolean,如果当前拦截器返回了个false表示拦截,则在它之后的拦截器就不再执行了。
*/
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("MyIntercepter06 preHandle start ...... ");
return true;
}
浏览器再次请求:http://localhost:8080/helloWorld
控制台打印结果。
因为05没有放行,所以helloWorld action仍然没有执行。
注意打印结果的顺序,preHandle先顺序打印,afterCompletion倒叙打印,并且postHandle没有执行。
并且 因为05不放行。06拦截器并没有执行。并且05的afterCompletion没有执行
接下来让04不放行,05 06都放行。
04拦截器
/**
* action之前会执行,所以拦截器的逻辑写在这里面。用于处理各种的需要拦截的操作,比如session检查,登录验证,权限等等。
* 返回值为boolean,如果当前拦截器返回了个false表示拦截,则在它之后的拦截器就不再执行了。
*/
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("MyIntercepter04 preHandle start ...... ");
return false;
}
05拦截器
/**
* action之前会执行,所以拦截器的逻辑写在这里面。用于处理各种的需要拦截的操作,比如session检查,登录验证,权限等等。
* 返回值为boolean,如果当前拦截器返回了个false表示拦截,则在它之后的拦截器就不再执行了。
*/
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("MyIntercepter05 preHandle start ...... ");
return true;
}
06拦截器不用动,刚才已经是放行状态了。
浏览器再次请求:http://localhost:8080/helloWorld
控制台打印结果。
因为04没有放行,所以helloWorld action仍然没有执行。
注意打印结果的顺序,preHandle先顺序打印,afterCompletion倒叙打印,并且postHandle没有执行。
并且 因为04不放行。05 06拦截器都没有执行。并且04的afterCompletion没有执行
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
到此可以得出结论,
1 同组的拦截器其中有一个不放行,后面的拦截器都不会执行,所以配置的时候应该将优先级高的拦截器放到前面,让其先执行,
2 同组的拦截器的preHandle是顺序执行,afterCompletion是倒叙执行。
3 同组的拦截器的某一个拦截器不放行,则它的afterCompletion也不会执行。
4 同组的拦截器只要有一个拦截器不放行,postHandle都不会执行。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
下面在看看拦截器都放行的结果。所有的preHandle的返回值都设为true
浏览器再次请求:http://localhost:8080/helloWorld
控制台打印结果。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
由上可以再得出结论,
5 只有preHandle全部放行,postHandle才会执行,并且同样也是倒叙执行。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
拦截器主要做什么用,比如校验某些session,
某些操作需要登录才能做,这时候需要做登录校验,
如果没登录,调到登录页面,如果已经登录,则将登录信息重新放入session中,以防止过期。
权限校验等等。
拦截器到此结束,主要就是理解,以及如何配置全局拦截器, 如何配置某些请求的拦截器,以及如果写拦截器。
springmvc的基本要点差不多就这些了。
下节将分析源码,看springmvc的执行流程,怎么在代码中实现,以及今天的拦截器为什么回事这个执行过程。
上一篇: SpringMVC&&&拦截器基本配置
下一篇: SVN配置自启动-1053错误
推荐阅读
-
深入分析C#键盘勾子(Hook)拦截器,屏蔽键盘活动的详解
-
SpringMVC拦截器实现监听session是否过期详解
-
Spring Boot使用过滤器和拦截器分别实现REST接口简易安全认证示例代码详解
-
详解SpringBoot 解决拦截器注入Service为空问题
-
SpringBoot的拦截器中依赖注入为null的解决方法
-
Struts2拦截器Interceptor的原理与配置实例详解
-
深入分析C#键盘勾子(Hook)拦截器,屏蔽键盘活动的详解
-
mybatis拦截器与分页插件实例教程
-
Spring Boot使用过滤器和拦截器分别实现REST接口简易安全认证示例代码详解
-
SpringBoot快速设置拦截器并实现权限验证的方法