SpringBoot Web开发——拦截器的基本使用

SpringBoot Web开发——拦截器的基本使用

文章目录

    • SpringBoot Web开发——拦截器的基本使用
      • 1.拦截器简介
      • 2.为什么需要使用拦截器?
      • 3.代码实现登录拦截
        • 3.1 控制层将登录成功的用户名添加至Session中
        • 3.2 自定义登录拦截器类
        • 3.3 配置类中注册拦截器
        • 3.4 测试登录拦截:直接访问index首页

1.拦截器简介

拦截器会对处理器进行拦截,拦截的目的就是做一些预处理,以此来增强处理器的功能。

常见的拦截器使用场景:

  • 登录拦截:身份验证
  • 日志记录:记录请求信息的日志
  • 性能监控:记录处理器方法执行时间。

下面以登录请求为例,简单使用拦截器,来实现登录拦截。

2.为什么需要使用拦截器?

比如一个XX后台管理系统,首先需要登录:

假设路径为: http://localhost:8080/login

输入账号信息登录后进入XX后台管理系统主页: http://localhost:8080/index

那如果直接访问http://localhost:8080/index呢?还是会返回主页,那这登录有啥意义呢?

而使用拦截器的话,浏览器请求http://localhost:8080/index时,拦截器可做预处理,判断会话对象Session中是否存在用户信息,不存在则跳转登录界面。

3.代码实现登录拦截

3.1 控制层将登录成功的用户名添加至Session中

使用前端使用thymeleaf模板引擎,浏览器GET请求/login和/index返回对应的html,还有一个/login的POST请求用于登录。

和之前没有登录拦截的区别:多了个HttpSession httpSession参数,前端请求不用管,登录成功后将用户名保存至Session中:

httpSession.setAttribute("loginUser",username);//将登陆成功的用户名添加至Session中

完整如下:

@Controller
public class TestController {

    Map<String, Object> result;

    @GetMapping("/login")
    public String login() {
        return "login";
    }
    
    @PostMapping("/login")
    @ResponseBody
    public Map<String, Object> login(@RequestParam("username") String username,
                                     @RequestParam("password") String password,
                                     HttpSession httpSession) {
        result = new HashMap<>();
        if (username.equals("123") && "123".equals(password)) {
            httpSession.setAttribute("loginUser",username);//将登陆成功的用户名添加至Session中
            result.put("resultCode", 200);
            return result;//登陆成功,前端根据resultCode跳转主页面
        } else {//登录失败
            result.put("resultCode", 500);
            return result;
        }
    }

    @GetMapping("/index")
    public String index() {
        return "index";
    }
}

3.2 自定义登录拦截器类

  • 使用@Component标注该拦截器类,将其添加至IOC容器

  • 实现HandlerInterceptor接口中的三个方法preHandle/postHandle/afterCompletion

这三个方法分别在DispatcherServlet之前执行/之后执行/结果返回给客户端之前执行,我们如果需要拦截登录,当然是在DispatcherServlet之前执行,也就是前端发送了我们指定拦截的请求路径后,我们先执行这个方法,再处理请求。

具体到登录拦截,判断上述添加至session中的loginUser是否存在,存在的话说明已经登录过,可放行请求,session中的loginUser为空的话,说明没有登录过,则返回至登录界面。

详情可看注释:

@Component
public class LoginInterceptor implements HandlerInterceptor {
    //在DispatcherServlet之前执行
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("1.我是在DispatcherServlet之前执行的方法");
        Object loginUser = request.getSession().getAttribute("loginUser");//获取已登录的用户名
        if (loginUser == null) {
            //未登录,返回登陆页面
            request.setAttribute("msg", "请先登录");
            request.getRequestDispatcher("/login").forward(request, response);//前端可获取request中的msg,来提示用户“请先登录”
            return false;
        } else {
            //已登录,放行请求
            return true;
        }
    }

    //在DispatcherServlet之后执行
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("2.在controller执行之后的DispatcherServlet之后执行");
    }

    //在页面渲染完成返回给客户端之前执行
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("3.在页面渲染完成返回给客户端之前执行");
    }
}

3.3 配置类中注册拦截器

项目中一般都会有配置类,即实现WebMvcConfigurer接口的类:

只需重写addInterceptors方法即可,使用回调参数InterceptorRegistry对象中的这三个方法:

  • addInterceptor():添加拦截器,传入拦截器对象
  • addPathPatterns():添加需要拦截的请求路径,若为/demo/**代表/demo下所有请求
  • excludePathPatterns():排除不需要拦截的请求路径,以登录为例,进入登录页面的/login当然要排除
@Configuration
public class MyConfig implements WebMvcConfigurer {


    @Resource
    private LoginInterceptor loginInterceptor;

    //注册拦截器,springboot已经做好静态资源(js/css等)的映射,无需额外配置
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor)//增加过滤的方法类
                .addPathPatterns("/**")//定义过滤的范围,拦截/下所有请求
                .excludePathPatterns("/login");//排除某些请求,这些请求无需拦截
    }

    //其他配置...
}

3.4 测试登录拦截:直接访问index首页

效果就是直接访问index管理界面会被拦截,自动跳转至登录界面。正常登录跳转还是和以前一样。

你可能感兴趣的:(#,SpringBoot)