拦截器
1. 拦截器应用场合:
用户发送请求到 DispatcherServlet,DispatcherServlet调用 HandlerMapping查找 Handler,HandlerMapping返回一个拦截器栈;
在企业开发中,使用拦截器实现用户认证、用户权限…
日志,异常拦截器必须要做,放在拦截器栈的第一位,且必须放行;
2. 拦截器的定义及使用方式:
1.创建拦截器,实现 HandlerInterceptor接口;
2.springmvc.xml 中配置拦截器:
测试结果:
情况一:1号和2号都放行(即MyInterceptor1、MyInterceptor2中 preHandle方法都返回 true):执行 preHandle是顺序,postHandle、afterCompletion是倒序;
情况二:1号放行,2号不放行(即MyInterceptor1中 preHandle方法都返回 true,MyInterceptor2中 preHandle方法都返回 false):只要有一个拦截器不放行,页面就无法显示;如果 preHandle不放行,其他两个方法就不执行;
情况三:1号、2号都不放行(即MyInterceptor1、MyInterceptor2中 preHandle方法都返回 false):只有前面的拦截器 preHandle方法放行,后面的拦截器才会执行 preHandle方法;
情况一打印结果:
MyInterceptor1…preHandle
MyInterceptor2…preHandle
MyInterceptor2…postHandle
MyInterceptor1…postHandle
MyInterceptor2…afterCompletion
MyInterceptor1…afterCompletion
情况一打印结果:
MyInterceptor1…preHandle
MyInterceptor2…preHandle
MyInterceptor1…afterCompletion
eg:
1. springmvc.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.asd.interceptor.MyInterceptor1"></bean>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.asd.interceptor.MyInterceptor2"></bean>
</mvc:interceptor>
</mvc:interceptors>
</beans>
2. MyInterceptor1.java
public class MyInterceptor1 implements HandlerInterceptor{
//执行Handler之后执行
public void afterCompletion(HttpServletRequest arg0,HttpServletReponse arg1,
Object arg2,Exception arg3) throws Exception{
System.out.println("MyInterceptor1...afterCompletion");
}
//执行Handler,返回ModelAndView之前
public void postHandle(HttpServletRequest arg0,HttpServletReponse arg1,
Object arg2,Exception arg3) throws Exception{
System.out.println("MyInterceptor1...postHandle");
}
//执行Handler之前执行
public boolean preHandle(HttpServletRequest arg0,HttpServletReponse arg1,
Object arg2,Exception arg3) throws Exception{
System.out.println("MyInterceptor1...preHandle");
//return false表示拦截,return true表示放行
return true;
}
}
2’. MyInterceptor2.java
public class MyInterceptor2 implements HandlerInterceptor{
//执行Handler之后执行
public void afterCompletion(HttpServletRequest arg0,HttpServletReponse arg1,
Object arg2,Exception arg3) throws Exception{
System.out.println("MyInterceptor2...afterCompletion");
}
//执行Handler,返回ModelAndView之前
public void postHandle(HttpServletRequest arg0,HttpServletReponse arg1,
Object arg2,Exception arg3) throws Exception{
System.out.println("MyInterceptor2...postHandle");
}
//执行Handler之前执行
public boolean preHandle(HttpServletRequest arg0,HttpServletReponse arg1,
Object arg2,Exception arg3) throws Exception{
System.out.println("MyInterceptor2...preHandle");
//return false表示拦截,return true表示放行
return true;
}
}
拦截器应用
需求:
用户认证:用户访问资源URL,如果没有认证,进行拦截,跳转到登录页面;如果用户认证通过,继续访问系统资源;
1.用户登录及退出功能;
2.用户身份认证拦截;
实现思路:
http请求:是公开地址时,不需要认证直接访问;
不是公开地址时,session中存在用户,正常访问,不存在用户,重定向到登录页面;
1. LoginController.java
在这里插入代码片
2. LoginInterceptor.java
public class LoginInterceptor implements HandlerInterceptor{
public void afterCompletion(HttpServletRequest arg0,HttpServletReponse arg1,
Object arg2,Exception arg3) throws Exception{
}
public void postHandle(HttpServletRequest arg0,HttpServletReponse arg1,
Object arg2,Exception arg3) throws Exception{
}
//执行Handler之前执行
public boolean preHandle(HttpServletRequest arg0,HttpServletReponse arg1,
Object arg2) throws Exception{
//得到请求的URL
String url=arg0.getRequestURL().toString();
//判断是否公开
if (url.indexOf("login.action")>0) {
return true;
}
HttpSession session=arg0.getSession();
String username=(String)session.getAttribute("username");
//用户信息是否存在
if (username!=null) {
return true;
}
//跳转到登录页面
arg0.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(arg0,arg1);
return false;
}
}
3. login.jsp
<body>
<form action="${pageContext.request.contextPath}/login.action">
用户名:<input type="text" name="username"/><br/>
密码:<input type="text" name="password"/><br/>
<input type="submit" name="登录"/>
</form>
</body>
4. itemsList.jsp
<body>
...
<c:if test="${username!=null}">
${username}
<a href="${pageContext.request.contextPath}/loginout.action">退出</a>
</c:if>
...
</body>
5. springmvc.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置登录拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.asd.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
</beans>