在 Spring Boot 项目中, 拦截器是开发中常用手段,要来做登陆验证、性能检查、日志记录等。
基本步骤:
√ 编写一个拦截器实现 HandlerInterceptor 接口
√ 拦截器注册到配置类中(实现 WebMvcConfigurer 的 addInterceptors)
√ 指定拦截规则
● 浏览器输入 : http://localhost:8080/manage.html , 如果用户没有登录,则返回登录界面.
1.创建src\main\java\com\llp\springboot\interceptor\LoginInterceptor.java
@Slf4j
@Component
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 {
//看看requestURI 和 requestURL的区别
String requestURI = request.getRequestURI();
String requestURL = request.getRequestURL().toString();
//URI=/manage.html
log.info("preHandle拦截到的请求的URI={}", requestURI);
//URL=http://localhost:8080/manage.html
log.info("preHandle拦截到的请求的URL={}", requestURL);
Object admin = request.getSession().getAttribute("admin");
if (admin != null) {
return true;
}
//拦截, 重新返回到登录页面
//adminLogin.html 去除msg的方式是从request域获取
request.setAttribute("msg", "您尚未登录,请登录");
request.getRequestDispatcher("/").forward(request, response);
return false;
}
/**
* 在目标方法被执行后执行. 可以在方法中访问到目标方法返回的 ModelAndView 对象
* 若 preHandle 返回 true, 则 afterCompletion 方法 在渲染视图之后被执行.
* 若 preHandle 返回 false, 则 afterCompletion 方法不会被调用
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("postHandle 执行了。。。");
}
/**
* 在渲染视图之后被执行.
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
log.info("afterCompletion 执行了。。。");
}
}
2.创建src\main\java\com\llp\springboot\config\WebConfig.java对我们定义的拦截器进行注册拦截路径配置
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
/**
* 1.拦截器会先拦截controller的路径映射
* 2.如果找不到则去静态资源下查找
* 3.这里配置/**会拦截所有的请求,包括静态资源
* 4.这里不拦截静态资源,为什么直接写成 "/images/**","/css/**" ?
* 5.在SpringBoot中引入了spring-boot-starter-web 依赖,每个starter都会对于的自动装配
* 6.在WebProperties中配置了类路径映射,因此可以直接省略/static/
* private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
* "classpath:/resources/", "classpath:/static/", "classpath:/public/" };
*
*/
registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/","/login","/images/**","/css/**");
}
}
3.修改src\main\java\com\llp\springboot\controller\AdminController.java
@Controller
public class AdminController {
@PostMapping("/login")
public String login(Admin admin, HttpSession session, Model model) {
if (StringUtils.hasText(admin.getUsername()) && "666".equals(admin.getPassword())) {
//1.这里使用重定向,不适用请求转发,防止刷新页面表单重复提交
//2./manage.html /会被解析成ip:port ,而manage.html是指定浏览器下一次请求访问的路径
//3.重定向会发起get请求
System.out.println(admin);
session.setAttribute("admin", admin);
return "redirect:/manage.html";
} else {
model.addAttribute("msg", "密码错误");
return "adminLogin";
}
}
@GetMapping("manage.html")
public String manage(Model model, HttpSession session) {
//可以这里集合-模拟用户数据, 放入到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";
}
}
测试效果
1、URI 和 URL 的区别
URI = Universal Resource Identifier URL = Universal Resource Locator Identifier:标识符,
Locator:定位器 从字面上来看, URI 可以唯一标识一个资源, URL 可以 提供找到该资源的路径
2、注册拦截器, 依然可以使用如下方式
@Configuration
public class WebConfig {
@Bean
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LocaleChangeInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/","/login","/images/**","/css/**");
}
};
}
}