前言
通常在一些特定的场景下,我们需要拦截器对用户的请求进行筛选,例如大部分应用都有登录的功能,这个时候就应该对用户发起的请求进行判断,拦截下所有非登录的请求,以维护网站的安全性。
一、准备工作
项目目录:
现在我们有两个界面,分别是用户登录界面index.html以及用户登录成功的界面show.html,我们先将这两个界面以及相应的请求添加至容器:
package com.tracy.springbootdemo.config;
import com.tracy.springbootdemo.component.LoginInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* Created by Tracy on 2020/3/20 12:26
*/
@Component
public class MySpringBootConfig implements WebMvcConfigurer {
@Bean
public WebMvcConfigurer webMvcConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
registry.addViewController("/about.html").setViewName("show");
}
};
}
}
二、注册拦截器
现在我们希望对用户登录前的请求进行部分拦截,编写登录的拦截类并实现HandlerInterceptor,代码如下:
package com.tracy.springbootdemo.component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Created by Tracy on 2020/3/21 15:17
*/
public class LoginInterceptor implements HandlerInterceptor {
//在目标方法执行之前
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//从发起的请求会话中获取loginUser字段
Object user = request.getSession().getAttribute("loginUser");
if (user == null) { //如果没有传来该参数,则需要用户先进行登录
request.setAttribute("msg", "Please login first !");
//获得转发器,重新定位到登录界面
request.getRequestDispatcher("/").forward(request, response);
return false;
}
return true; //返回为false时将不会执行后续的操作
//返回为true时请求继续执行后续的操作
}
}
接下来把拦截器组件加入至容器,编写MySpringBootConfig类:
package com.tracy.springbootdemo.config;
import com.tracy.springbootdemo.component.LoginInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* Created by Tracy on 2020/3/20 12:26
*/
@Component
public class MySpringBootConfig implements WebMvcConfigurer {
@Bean
public WebMvcConfigurer webMvcConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
registry.addViewController("/about.html").setViewName("show");
}
//注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
//springboot做好了静态资源拦截映射, 可直接访问 //先对所有资源访问进行拦截
registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**")
//对指定资源路径放行 (一定要对发起的请求进行放行!!)
.excludePathPatterns("/index.html", "/", "/login",
);
}
};
}
}
效果如下:
可以发现我们原本的样式消失了。原因是在SpringBoot2.x版本的拦截器是默认拦截静态资源的,所以我们只需要将静态资源写入拦截器的放行资源。
修改拦截器的内容:
//注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
//springboot做好了静态资源拦截映射, 可直接访问 //先对所有资源访问进行拦截
registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**")
//对指定资源路径放行 (一定要对发起的请求进行放行!!)
.excludePathPatterns("/index.html", "/", "/login",
//对静态资源进行放行
"/webjars/**",
"/assets/**", "assets2/**"
);
}
页面效果:
静态资源成功引入!
下面我们来编写控制类LoginController,代码如下:
package com.tracy.springbootdemo.controller;
import com.tracy.springbootdemo.bean.User;
import com.tracy.springbootdemo.entity.UserDaoImp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpSession;
import java.util.Map;
/**
* Created by Tracy on 2020/3/21 12:58
*/
@Controller
public class LoginController {
@Autowired
private UserDaoImp userDaoImp; //操作数据库的实现类
@PostMapping(value = "/login")
public String login(@RequestParam String id, @RequestParam String password,
Map<String, Object> map, HttpSession session) {
User user = userDaoImp.getUser(id); //通过id从数据库中获取用户
System.out.println(user);
if (user == null) { //如果没有该用户
map.put("NoUser", "The account isn't exist !");
return "index";
} else if(!user.getPassword().equals(password)) { //如果密码错误
map.put("Error", "The userInfo not match !");
return "index";
} else { //如果正确输入
map.put("user", user.getName());
//为拦截器提供loginUser参数,内容为该用户的名字
session.setAttribute("loginUser", user.getName());
//重定向到用户界面,拦截器解除
return "redirect:/about.html";
}
}
}
运行效果:
1、直接访问用户界面:
请求被拦截,拦截器加入成功!
2、正确输入账号密码:
页面跳转成功!!