一.概述
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>
/** :所有请求都拦截