拦截器-HandlerInterceptor
2023年11月17日大约 4 分钟约 873 字
基本介绍
在 Spring Boot 项目中,拦截器是开发中常用手段,要来做登陆验证、性能检查、日志 记录等。
基本步骤:
编写一个拦截器实现 HandlerInterceptor 接口
拦截器注册到配置类中(实现 WebMvcConfigurer 的 addInterceptors)
指定拦截规则
应用实例
需求
使用拦截器防止用户非法登录。浏览器输入:http://localhost:8080/manage.html
,如果用户没有登录,则返回登录界面。
代码实现
修改 AdminController.java
package com.lzw.springboot.controller;
import com.lzw.springboot.bean.Admin;
import com.lzw.springboot.bean.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
/**
* @author LiAng
*/
@Controller
@Slf4j
public class AdminController {
//处理用户的请求到 manage.html
@GetMapping("/manage.html")
public String mainPage(Model model, HttpSession session) {
log.info("进入到 mainPage()");
//这里用集合-模拟用户数据, 放入到request域中,并显示
ArrayList<User> users = new ArrayList<>();
users.add(new User(1, "关羽~", "666666", 20, "gy@sohu.com"));
users.add(new User(2, "张飞", "666666", 30, "zf@sohu.com"));
users.add(new User(3, "赵云", "666666", 22, "zy@sohu.com"));
users.add(new User(4, "马超", "666666", 28, "mc@sohu.com"));
users.add(new User(5, "黄忠", "666666", 50, "hz@sohu.com"));
//将数据放入到request域
model.addAttribute("users", users);
return "manage"; //这里才是我们的视图解析到 /templates/manage.html
}
}
修改 manage.html
<a href='#'>返回管理界面</a> <a href='#' th:href="@{/}">安全退出</a> 欢迎您:
现在可以不登录,就访问到管理页面

测试完再把这句加上
<a href='#'>返回管理界面</a> <a href='#' th:href="@{/}">安全退出</a> 欢迎您:[[${session.loginAdmin.name}]]
创建 src/main/java/com/lzw/springboot/interceptor/LoginInterceptor.java
package com.lzw.springboot.interceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* @author LiAng
*/
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
/**
* 目标方法执行前被调用.
*
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String requestURI = request.getRequestURI();
String requestURL = request.getRequestURL().toString();
log.info("preHandle拦截到的请求的URI={}", requestURI);
log.info("preHandle拦截到的请求的URL={}", requestURL);
//进行登录的校验
HttpSession session = request.getSession();
Object loginAdmin = session.getAttribute("loginAdmin");
if(loginAdmin != null){//说明该用户已经成功登录
//放行
return true;
}
//拦截, 重新返回到登录页面
request.setAttribute("msg", "你没有登录/请登录~~");
request.getRequestDispatcher("/").forward(request, response);
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("postHandle执行了...");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
log.info("afterCompletion执行了...");
}
}
创建 src/main/java/com/lzw/springboot/config/WebConfig.java
package com.lzw.springboot.config;
import com.lzw.springboot.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author LiAng
*/
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//注册自定义拦截器 LoginInterceptor
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**") //拦截所有的请求
.excludePathPatterns("/","/login","/images/**");//指定要放行的,后面可以根据业务需求,来添加放行的请求路径
}
}


注意事项和细节
1、URI 和 URL 的区别
URI = Universal Resource Identifier
URL = Universal Resource Locator
Identifier:标识符,Locator:定位器。从字面上来看,URI 可以唯一标识一个资源,URL 可以提供找到该资源的路径。
2、注册拦截器,还可以使用如下方式
package com.lzw.springboot.config;
import com.lzw.springboot.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author LiAng
*/
@Configuration
public class WebConfig /**implements WebMvcConfigurer */ {
//@Override
//public void addInterceptors(InterceptorRegistry registry) {
//
// //注册自定义拦截器 LoginInterceptor
// registry.addInterceptor(new LoginInterceptor())
// .addPathPatterns("/**") //拦截所有的请求
// .excludePathPatterns("/","/login","/images/**");//指定要放行的,后面可以根据业务需求,来添加放行的请求路径
//}
//第二种方式
@Bean
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
@Override
public void addInterceptors(InterceptorRegistry registry) {
System.out.println("addInterceptors~~~");
//注册拦截器
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/","/login","/images/**");
}
};
}
}