SpringMVC拦截器
一、理解
SpringMVC的处理器拦截器类似于Servlet中的过滤器Filter,用于对处理器进行预处理和后处理。另外,开发者可以自定义一些拦截器来实现特定的功能
二、过滤器和拦截器的区别
拦截器是AOP思想的具体应用,横切进去,不影响代码
1、过滤器:
Servlet规范中的一部分,任何java web工程都可以使用,为了不处理垃圾请求
在url-pattern中配置了/*之后,可以对要访问的资源进行拦截
<!-- 配置SpringMVC乱码过滤-->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2、拦截器
拦截器是SpringMVC框架自己的,只有使用SpringMVC框架工程才能使用
拦截器只会拦截访问的控制器方法,如果要访问jsp/html/css/image/js等静态资源是不会进行拦截的
自定义拦截器
一、写一个类,继承handlerInterceptor接口,重写接口中的方法(接口中的方法不是一定要被重写的,也可以自定义)
//自定义拦截器,直接实现HandlerInterceptor接口
public class MyInterceptor implements HandlerInterceptor {
/*
return true:表示执行下一个拦截器,放行
return false:表示不执行下一个拦截器,直接将方法停止在拦截器上,不允许穿透拦截器
*/
//一般情况下,拦截功能只是用拦截前方法即可,下面两个postHandle、afterCompletion一般都是些一些拦截的日志信息(可以省略)
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("===========拦截前===========");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("===========拦截后===========");
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("===========清理===========");
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
二、在spring-mvc.xml配置文件配置拦截器
<!-- 配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!-- /**表示所有的请求都会被拦截,包括父子映射路径的情况-->
<mvc:mapping path="/**"/>
<bean class="com.guohui.config.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
三、对return true 和false的理解
1、return true的情况
会执行拦截前、执行方法,并且还能执行其他的拦截方法,是放行状态
2、return false的情况
(1)首先我将拦截前的方法的返回值改成了false
(2)启动服务器,控制台打印
如果设置return false,那么就表示不执行下一个拦截器,控制器方法也不会执行,我们可以在这个时候做一些判断,如果不符合条件,直接将页面跳转到首页的情况
用拦截器实现登陆判断验证
一、编写首页
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>首页</title>
</head>
<body>
<h1>欢迎你!!!</h1>
</body>
</html>
二、编写登陆页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登陆页面</title>
</head>
<body>
<h2>登陆页面</h2>
<%--在WEB-INF下的所有页面或者资源,只能通过Controller或者Servlet进行访问--%>
<form action="${pageContext.request.contextPath}/login" method="post">
账号:<input type="text" name="username">
密码:<input type="password" name="pwd">
<input type="submit" value="登陆">
</form>
<span id="error" style="color:red;">${error}</span>
</body>
</html>
三、编写拦截器类
import org.aopalliance.intercept.Interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//如果当前是在登陆的页面,也要进行放行,允许进入首页
if (request.getRequestURL().indexOf("login") > -1){
return true;
}
//点击首页前做一步校验,如果这个session中有值,则放行return true
if (request.getSession().getAttribute("username") != null) {
return true;
}
//这一步就是表示当我除了以上情况都会被拦截,然后转发到登陆页面
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
return false;
}
}
四、在spring-mvc.xml配置文件中配置拦截器
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 注解驱动,配置扫描包,这个包下的注解有效-->
<context:component-scan base-package="com.guohui.controller"/>
<!-- 配置处理映射器和适配器-->
<!-- 配置annotation-driven,帮我们节省了配置处理器映射器HandlerMapping和处理器适配器HandlerAdapter-->
<mvc:annotation-driven>
<!-- 配置JSON解决乱码问题,死代码,以后直接用就行-->
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8"/>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="failOnEmptyBeans" value="false"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 配置不处理静态资源-->
<mvc:default-servlet-handler/>
<!-- 配置视图解析器
在视图解析器中,我们把所有的视图都放在WEB-INF下,这样可以保证视图安全,因为这个目录下的文件,客户不能直接访问-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<!-- 前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!-- 后缀-->
<property name="suffix" value=".jsp"/>
</bean>
<!-- 配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!-- /**表示所有的请求都会被拦截,包括父子映射路径的情况-->
<mvc:mapping path="/**"/>
<bean class="com.guohui.config.MyInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.guohui.config.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
五、测试
1、点击首页,被拦截,进入登陆页面
2、点击登陆页面,输入密码成功,则跳转到首页
六、总结
拦截器核心思想就是AOP,在不影响原本代码的同时,对配置的控制器进行执行前拦截,对他们的条件加以判断,如果符合条件放行,允许往下执行或者走下一个拦截器,如果不满足判断条件,则阻止他往下一个方法走,我们还可以人为控制如果不满足条件,让页面转发到某个页面。
至此,你已经深入的掌握了关于SpringMVC拦截器的技术点,后续还会持续更新!