一 拦截器
1.1 springboot整合拦截器
1.1.1 自定义拦截器
1.实现HandlerInterceptor接口,重写3个方法的逻辑
preHandle:调用Controller某个方法之前
postHandle:Controller之后调用,视图渲染之前,如果控制器Controller出现了异常,则不会执行此方法
afterCompletion:不管有没有异常,这个afterCompletion都会被调用,在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)
1.1.2 将自定义拦截器注册到配置文件中
在所在类必须配置@Configuration,SpringBoot2.X 新版本配置拦截器 implements WebMvcConfigurer
1.2 多个拦截器加载顺序
按照注册顺序进行拦截,先注册,先被拦截
1.3 拦截器和过滤器的区别
Filter是基于函数回调 doFilter(),而Interceptor则是基于AOP思想
Filter在只在Servlet前后起作用,而Interceptor够深入到方法前后、异常抛出前后等
依赖于Servlet容器即web应用中,而Interceptor不依赖于Servlet容器所以可以运行在多种环境。
在接口调用的生命周期里,Interceptor可以被多次调用,而Filter只能在容器初始化时初始化一次,在每次请求时创建一个新的action。一次请求只能调用一次filter,。
Filter和Interceptor的执行顺序:过滤前->拦截前->action执行->拦截后->过滤后
1.4 拦截器,过滤器,监听器
二 拦截器操作案例
2.1 项目结构
2.2 背景描述.
1.对访问路径中含有api的请求,则放行,在controller层设置session信息,然后跳转到zhong.html页面,从zhong.html请求toglogin,进入contoller,再次跳转到main.html页面,
2.可以在处理完controller信息后,在视图渲染前,对设置的信息就行修改。
2.3 pom文件配置
<!--spring boot的启动类 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- springBoot的启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2.4 controller层
package com.ljf.spring.boot.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Map;
import java.util.TreeMap;
/**
* @ClassName: UserController
* @Description: TODO
* @Author: liujianfu
* @Date: 2021/04/06 10:19:22
* @Version: V1.0
**/
@Controller
public class UserController {
@RequestMapping("/api")
public String show(HttpServletRequest request, HttpServletResponse response, HttpSession session){
System.out.println("自定义拦截器....,进入controller!!!!");
session.setAttribute("username","liu");
return "zhong";//跳转到zhong这个html页面
}
@RequestMapping("/toLogin")
public ModelAndView toLogin(HttpServletRequest request, HttpServletResponse response, HttpSession session){
System.out.println("自定义拦截器....,进入controller!!!!");
ModelAndView modelAndView=new ModelAndView();
modelAndView.addObject("username","liu");
modelAndView.setViewName("main");
return modelAndView;
}
}
2.5 自定义过滤器
package com.ljf.spring.boot.demo.intercepter;
import com.ljf.spring.boot.demo.model.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @ClassName: LoginIntercepter
* @Description: TODO
* @Author: liujianfu
* @Date: 2021/04/06 10:26:53
* @Version: V1.0
**/
public class LoginIntercepter implements HandlerInterceptor {
/**
* 进入controller方法之前
*/
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
System.out.println("LoginIntercepter------->preHandle");
try {
//统一拦截(查询当前session是否存在user)(这里user会在每次登陆成功后,写入session)
String name=(String)request.getSession().getAttribute("username");
if(name!=null){
return true;
}
//放开的支援
String loginUrl=(String)request.getRequestURL().toString();
System.out.println("context:"+request.getContextPath()+" url:"+loginUrl);
if(loginUrl.indexOf("/api")!=-1){
return true;
}
response.sendRedirect(request.getContextPath()+"你的登陆页地址");
} catch (IOException e) {
e.printStackTrace();
}
return false;//如果设置为false时,被请求时,拦截器执行到此处将不会继续操作
//如果设置为true时,请求将会继续执行后面的操作
}
/**
* 调用完controller之后,视图渲染之前执行
*/
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
String ad=(String)request.getAttribute("address");
modelAndView.addObject("username","在intercepter的postHandle方法设置的");
System.out.println("LoginIntercepter------->postHandle"+ad);
}
/**
* 在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)
*/
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("LoginIntercepter------->afterCompletion");
}
}
2.6 在配置文件中注册过滤器
package com.ljf.spring.boot.demo.config;
import com.ljf.spring.boot.demo.intercepter.LoginIntercepter;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @ClassName: SptWebMvcConfigurer
* @Description: TODO
* @Author: liujianfu
* @Date: 2021/04/06 10:57:33
* @Version: V1.0
**/
@Configuration
public class SptWebMvcConfigurer implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//注册TestInterceptor拦截器
InterceptorRegistration registration = registry.addInterceptor(new LoginIntercepter());
registration.addPathPatterns("/**"); //所有路径都被拦截
registration.excludePathPatterns( //添加不拦截路径
"你的登陆路径", //登录
"/**/*.html", //html静态资源
"/**/*.js", //js静态资源
"/**/*.css", //css静态资源
"/**/*.woff",
"/**/*.ttf"
);
}
}
2.7 静态资源
1.login.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>欢迎登录登录首页!!!</h1>
</body>
</html>
2.main.html
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>!!!!!!!!欢迎来到主页面=====</h1>
<td th:text="${username}"></td>
</body>
</html>
3.zhong.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1><a href="http://localhost:8080/toLogin">登录</a>!!!</h1>
</body>
</html>
2.8 启动
package com.ljf.spring.boot.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Hello world!
*
*/
@SpringBootApplication
public class App
{
/**
* @author liujianfu
* @date 2020/7/23 0023 下午 2:45
* @param [args]
* @return void
*/
public static void main( String[] args )
{
SpringApplication.run(App.class);
System.out.println("启动完成!!!");
}
}
2.9 访问
点击页面的登录连接: