一.概述
springmvc的处理拦截器类似于servlet开发中的过滤器Filter,用于对处理器预处理和处理,开发者可以自定义一些拦截器来实现特定的功能
拦截器与过滤器的区别:拦截器是AOP思想的具体应用
过滤器:
- servlet规范中的一部分,任何Java web工程都可以使用
- 在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截
拦截器:
- 拦截器是springmvc框架自己,只有使用了springmvc的框架工程才能使用
- 拦截器只会拦截访问的控制方法,如果访问的是jsp/html/css/image/js是不会进行拦截的
二.自定义拦截器
1.编写一个请求:
@RestController
public class MyController {
@RequestMapping("/a1")
public String test(){
System.out.println("MyController===>执行了");
return "ok";
}
}
2.拦截器:需要实现接口 : HandlerInterceptor
public class MyInterceptor implements HandlerInterceptor {
//return false; 被拦截,不会发往下一站
//return true; 不会被拦截,继续前往下一站(拦截器)
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("=========处理前=========");
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("=========处理后=========");
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("=========清理=========");
}
}
这个springMVC自带的拦截器有三个重写方法:
preHandle:拦截对配置路径下的所有的请求,并决定是否发往下一站
postHandle:当第一个方法允许以后,会在代码处理后在通过这个方法,根据情况进行拦截
afterCompletion:负责清理这些拦截请求和放行后产生的冗余数据
3.springmvc的xml文件的配置:
<!--拦截器的配置--> <mvc:interceptors> <mvc:interceptor> <!-- /** 表示所有的请求都会被拦截--> <!-- /page/** 表示page下的所有请求都会被拦截--> <mvc:mapping path="/**"/> <bean class="top.lostyou.config.MyInterceptor"/> </mvc:interceptor> </mvc:interceptors>
注:拦截器可以存在多个,配置方式都一样,需要在<mvc:interceptors></mvc:interceptors>中,通过后面的s也可以判断可以配置多个拦截器
4.测试结果展示:
总结:
由测试结果就可以看出拦截器三个方法所处的位置,但是既然作为拦截器,那么作用就一定是拦截,所以一般我们只会使用第一个方法,即拦截前:
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{
return true;
}
三.普通案例实现
1.设置一个首页:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>首页</h1> <span>${username}</span> </body> </html>
2.简单作一个表单,用来登录测试
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>用户登录界面</title> </head> <body> <%--在web-inf下面的所有页面或资源,只能通过controller,或者servlet进行访问--%> <h1>登录</h1> <form action="${pageContext.request.contextPath}/login" method="post"> <input type="text" name="username"/><br> <input type="text" name="password"/><br> <input type="submit" value="提交"> </form> </body> </html>
3.编写一个控制类:
@Controller
public class LoginContrroller {
@RequestMapping("/main")
public String main(){
return "main";
}
@RequestMapping("/goLogin")
public String login(){
return "Login";
}
@RequestMapping("/login")
public String login(HttpSession session, String username, String password, Model model){
System.out.println("成功存入!!!");
session.setAttribute("userInfo",username);
model.addAttribute("username",username);
return "main";
}
}
/login是登录的核心,当登录完成后,我们的session中就会放值,也是拦截是否放行的一个条件
4.拦截器的编写:
public class LoginInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//思考什么情况拦截,什么情况就放行
//如果请求地址中含有“login”,"goLogin",说明它正在请求登录,所以不拦截,本来设计的目的就是要它登录,所以放行
if(request.getRequestURI().contains("goLogin")){
return true;
}
if(request.getRequestURI().contains("login")){
return true;
}
//userInfo中有值说明已经登录过
if(request.getSession().getAttribute("userInfo")!=null){
return true;
}
//不满足以上两个情况就不放行,拦截下来
request.getRequestDispatcher("/WEB-INF/jsp/Login.jsp").forward(request,response);
return false;
}
}
其他的好理解,重点提一下 : request.getRequestURI().contains("goLogin")
这一句话的意思是判断请求中有无“goLogin”这个字符串,他会在地址栏中去找,如果有就放行,毕竟别人要去登录,设计的目的是为了防止未登录
5.配置springmvc的核心配置文件:
<mvc:interceptor> <mvc:mapping path="/**"/> <bean class="top.lostyou.config.LoginInterceptor"/> </mvc:interceptor>
/** :所有请求都拦截