• 喜欢前端以及PHP的朋友们可以加PHP同好会QQ群 点击加入qq群
  • 最近在写一个项目---"小A微信托管平台",大家可以去帮忙测试一下!功能在不断完善中,敬请关注!点击进入
  • 本站使用了PHP8.1与HTTP2.0协议,速度简直超级快有木有?

Spring Boot2 学习笔记之集成Interceptor(七)

后端 Mr.Adam 4年前 (2021-04-14) 1519次浏览 已收录 0个评论

Spring Boot2 学习笔记之集成 Interceptor(七)

Spring Boot2 学习笔记之集成 Interceptor(七)

过滤器 Filter 和 拦截器 Interceptor 的区别

Filter 是依赖于 Servlet 容器,属于 Servlet 规范的一部分,而拦截器则是独立存在的,可以在任何情况下使用。
Filter 的执行由 Servlet 容器回调完成,而拦截器通常通过动态代理的方式来执行。
Filter 的生命周期由 Servlet 容器管理,而拦截器则可以通过 IoC 容器来管理,因此可以通过注入等方式来获取其他 Bean 的实例,因此使用会更方便。
过滤器在 spring boot 调用的外层进行拦截,而拦截器则在 spring boot 加载 bean 之后进行拦截操作

编写一个拦截器

spring boot 中拦截器很简单,只要实现HandlerInterceptor 接口就可以
以下是一个计算请求执行时间的拦截器

public class LogCostInterceptor implements HandlerInterceptor {
    long start = System.currentTimeMillis();
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        start = System.currentTimeMillis();
        return true;
    }


    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("Interceptor cost="+(System.currentTimeMillis()-start));
    }


    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    }
}

这里我们需要实现 HandlerInterceptor 这个接口,这个接口包括三个方法,preHandle 是请求执行前执行的,postHandler 是请求结束执行的,但只有 preHandle 方法返回 true 的时候才会执行,afterCompletion 是视图渲染完成后才执行,同样需要 preHandle 返回 true,该方法通常用于清理资源等工作。除了实现上面的接口外,我们还需对其进行配置:

@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LogCostInterceptor()).addPathPatterns("/**");
        super.addInterceptors(registry);
    }
}

使用拦截器解析 Basic token 信息

我们开发网络应用中免不了要开发与授权相关的功能,授权的操作就非常适合放入拦截器.
以下是我编写的拦截器,用来解析 Basic token 信息,并将用户名放入请求参数中

@Slf4j
public class FirstInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        String token = httpServletRequest.getHeader("Authorization");
        String regex = "^Basic\\s.+$";
        if(token != null && token.matches(regex)){
            //获取 basic token
            log.info("token:{}",token);
            token = new String(Base64.getDecoder().decode(token.substring(6)),"UTF-8");
            log.info("获取的 Authorization token: {}",token);
            //basic token 格式为 username:password
            String[] res = token.split(":");
            if(res[0].equals("admin") && res[1].equals("111111")){
                //将用户名放入 req 中
                httpServletRequest.setAttribute("username",res[0]);
                return true;
            }else{
                JSONObject json = new JSONObject();
                //向 json 中添加数据
                json.put("code", 401);
                json.put("message", "用户名密码错误");
                String jsonStr = json.toString();
                httpServletResponse.setStatus(401);
                this.returnJson(httpServletResponse,jsonStr);
                return false;
            }
        }
        JSONObject json = new JSONObject();
        //向 json 中添加数据
        json.put("code", 403);
        json.put("message", "未授权");
        String jsonStr = json.toString();
        httpServletResponse.setStatus(403);
        this.returnJson(httpServletResponse,jsonStr);
        return false;
    }

    private void returnJson(HttpServletResponse response, String json) throws Exception{
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-type","application/json;charset=UTF-8");
        System.out.println("Default charset: " + response.getCharacterEncoding());
        log.info("返回值:{}",json);
        PrintWriter writer = response.getWriter();
        writer.write(json);
        writer.flush();
        writer.close();
    }


    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }


    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}

再编写一个controller进行测试

@RestController
@Slf4j
public class TestController {

    @GetMapping("testInterceptor")
    public Map<String,Object> testInterceptor(HttpServletRequest req){
        Map res = new HashMap<String,Object>();
        res.put("用户名",req.getAttribute("username"));
        return res;
    }

}

接下来我们再PostMan中进行测试:
用户名为admin,密码为111111才能通过拦截器
Spring Boot2 学习笔记之集成 Interceptor(七)
Spring Boot2 学习笔记之集成 Interceptor(七)
Spring Boot2 学习笔记之集成 Interceptor(七)


小 A 空间 , 版权所有丨如未注明转载 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明Spring Boot2 学习笔记之集成 Interceptor(七)
喜欢 (1)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址