当前位置: 首页 > article >正文

Springboot之拦截器Interceptor

1、Interceptor定义

Interceptor类似于Servlet中的过滤器,但是Interceptor是Spring boot所带的,它主要用于拦截用户请求并做出相应的处理。例如通过拦截器可以进行登录校正。

首先当用户登录成功时,需要生成令牌,并分发令牌。代码如下:

package yuyanan.controller;


import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import yuyanan.pojo.Emp;
import yuyanan.pojo.Result;
import yuyanan.service.EmpService;
import yuyanan.utils.JwtUtils;

import java.util.HashMap;
import java.util.Map;

@Slf4j
@RestController
public class LoginController {
    @Autowired
    private EmpService empService;

    @PostMapping("/login")
    public Result login(@RequestBody Emp emp){
        log.info("员工登录:{}", emp);

        Emp e = empService.login(emp);

        //登录成功,生成令牌,下发令牌
        if (e != null){
            Map<String, Object> claims = new HashMap<>();
            claims.put("id", e.getId());
            claims.put("name", e.getName());
            claims.put("username", e.getUsername());
            String jwt = JwtUtils.generateJwt(claims);    //jwt包含了当前登录的员工信息
            return Result.success(jwt);
        }
        //登录失败,返回错误信息
        return Result.error("用户名或者密码错误");
    }
}

在设置拦截器时需要注意,拦截器LoginCheckInterceptor需要实现HandlerInterceptor接口,并在preHandle方法中编写相应的代码,若该方法返回true,则放行;否则不放行。相应代码如下:

package yuyanan.Interceptor;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import yuyanan.pojo.Result;
import yuyanan.utils.JwtUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
@Component
public class LoginCheckInterceptor implements HandlerInterceptor {
    @Override   //目标资源方法运行前运行,返回true,放行;返回false,拦截
    public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {
        //1、获取请求url
        String url = req.getRequestURL().toString();
        log.info("请求的url:{}", url);

        //2、判断请求url中是否包含login,如果包含,说明是登录操作,放行
        if (url.contains("login")){
            log.info("登录操作,放行...");
            return true;
        }

        //3、获取请求头中的令牌(token)
        String jwt = req.getHeader("token");

        //4、判断令牌是否存在,如果不存在,返回错误结果(未登录)
        if(!StringUtils.hasLength(jwt)){
            log.info("请求头token为空,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换  对象--json ---------》阿里巴巴的fastJson
            String jsonString = JSONObject.toJSONString(error);
            resp.getWriter().write(jsonString);
            return false;
        }

        //5、解析token,如果解析失败,返回错误结果(未登录)
        try {
            JwtUtils.parseJWT(jwt);
        }catch (Exception e){    //jwt令牌解析失败
            e.printStackTrace();
            log.info("请求头token为空,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换  对象--json ---------》阿里巴巴的fastJson
            String jsonString = JSONObject.toJSONString(error);
            resp.getWriter().write(jsonString);
            return false;
        }


        //6、放行
        log.info("令牌合法,放行!");
        return true;

    }

    @Override  //目标资源方法运行后运行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle....");
    }

    @Override //视图渲染完毕后运行,最后运行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion...");
    }
}

由于需要将该类放入到容器中进行管理,因此在上面添加@Component注解。紧接着还需要添加一个配置类WebConfig,该配置类实现WebMvcConfigurer接口,并重写添加拦截器addInterceptors方法,在该方法中指出我们要添加的拦截器名字以及作用范围。代码如下:

package yuyanan.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import yuyanan.Interceptor.LoginCheckInterceptor;

@Configuration   //代表当前类是一个配置类
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private LoginCheckInterceptor loginCheckInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**");
    }
}

值得注意的是该类是一个配置类,因此在类上面添加@Configuration注解。

总结:
1、编写自己的拦截器类LoginCheckInterceptor并实现HandlerInterceptor接口,给该类添加注解@Component将其注入到容器中,重写preHandle方法。
2、编写配置类WebConfig并实现WebMvcConfigurer接口,添加@Configuration注解表明该类是一个配置类,在该类中重写addInterceptors方法,并将我们自己编写的拦截器类加入即可。


http://www.kler.cn/a/104805.html

相关文章:

  • asyncio教程
  • 【目标检测】非极大值抑制NMS的原理与实现
  • C/C++输出整数 2020年9月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析
  • 记录nvm use node.js版本失败,出现报错: exit status 1: ��û���㹻��Ȩ��ִ�д˲�����
  • 群面的技巧
  • 如何实现两栏布局?这篇文章告诉你所有的细节!
  • influxdb基本使用及其源码解析
  • Ubuntu 安装 npm 和 node
  • RabbitMQ原理(四):MQ的可靠性
  • 【linux】SourceForge 开源软件开发平台和仓库
  • 云游数智农业世界,体验北斗时空智能
  • 什么是web3.0?
  • 基于STM32+物联网设计的货车重量检测系统(OneNet)
  • 如何通过企业培训考试系统实现持续学习和发展
  • RabbitMQ的交换机(原理及代码实现)
  • PPT文档图片设计素材资源下载站模板源码/织梦内核(带用户中心+VIP充值系统+安装教程)
  • 【凡人修仙传】定档,四女神出场,韩立遭极阴岛陷阱,蛮胡子亮相
  • kvm webvirtcloud 如何添加直通物理机的 USB 启动U盘
  • Kotlin(八) 数据类、单例
  • 【QML】ListView 报错 ReferenceError: index is not defined