浅析springboot中拦截器的使用方法

浅析springboot中拦截器的使用方法

一、拦截器简介

产生背景:在面向对象开发的过程,我们可以通过继承、多态来解决纵向功能扩展问题。但是,对于横向功能扩展方面,比如给所有的服务开启事务,或者统一日志功能等,是没有办法实现的。所以就有了面向切面编程思想(AOP),它只是一种思想,是对面向对象思想的一种补充;于是就产生了拦截器,拦截器可以获取IOC容器中的任何bean;

二、拦截器功能用法

1.用法

  1. 定义个class类,实现HandlerInterceptor接口
  2. 选择拦截器中的拦截方式,并实现具体拦截内容

2.拦截方式

源码:

boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception;

void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)throws Exception;

void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception;

说明:

  1. preHandle:在业务处理前调用。属于预处理,可以进场权限校验,安全控制等处理;
  2. postHandle:在业务处理请求执行完成后,生成视图之前执行。属于后处理(调用了Service并返回ModelAndView,但未进行页面渲染),有机会修改ModelAndView
  3. afterCompletion:在DispatcherServlet完全处理完请求后被调用,可用于清理资源等。返回处理(已经渲染了页面)

三、使用实战

1.定义一个拦截器类,实现HandleInterceptor

package com.test0510.study.interceptor;

import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.*;

public class LoginInterceptor implements HandlerInterceptor {

  /**
   * 预处理拦截器
   */
  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
//    Enumeration<String> headerNames = request.getHeaderNames();
//    String header = request.getHeader("ib-web");
//    HttpSession session = request.getSession();
//    String contextPath = request.getContextPath();
//    Cookie[] cookies = request.getCookies();
//    HttpServletMapping httpServletMapping = request.getHttpServletMapping();
//    String queryString = request.getQueryString();
//    String s = request.changeSessionId();

    String requestURI = request.getRequestURI();
    // 拦截,并返回拦截原因
    if(requestURI.startsWith("/role/test")){
      log.debug("鉴权失败,无权限的请求路径!");
      this.err(response,request);
      return false;
    }
    // 不拦截,可通过的接口
    if(StringUtils.startsWithIgnoreCase(requestURI,"/learn/user")){
      return true;
    }
    return true;
  }
}

/**
   * 自定义拦截器报错提示信息
   * @param response
   */
  private void err(HttpServletResponse response,HttpServletRequest request){
    response.setContentType("application/json;charset=UTF-8");
    Map<String,String> map = new HashMap<>();
    map.put("code","400");
    map.put("errMessage","未开通访问权限的url");
    try(PrintWriter writer = response.getWriter()) {
      writer.write(JSONObject.toJSONString(map));
    }catch (IOException e){
      log.error(request.getRequestURI()+"无权限,已被拦截");
    }
  }

2.向容器中注入定义的拦截器

package com.test0510.study.config;

import com.test0510.study.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;


@Configuration
public class MvcConfig implements WebMvcConfigurer {

  /**
   * 在springmvc容器中添加拦截器
   * @return
   */
  @Bean
  public LoginInterceptor loginInterceptor(){
    return new LoginInterceptor();
  }


  // 此处样例为拦截"/learn"开头的模块的url,不添加具体模块,会将swagger等测试工具也拦截掉
  @Override
  public void addInterceptors( InterceptorRegistry registry) {
    registry.addInterceptor(loginInterceptor()).addPathPatterns("/learn/**") // 拦截learn开头的url
        .order(1)   // 值越小,优先级越高
        .excludePathPatterns(
            "/learn/hello"
            ,"/learn/user"
        );    // 排除拦截"/learn/hello","/learn/user"的url
  }

}

3.结果:

  • url是"/role/test"会被拦截,因为其被配置在了拦截器中;
  • url是learn开头的会被拦截,但是"/learn/hello"和"/learn/user"两个url除外,注入容器的拦截方式配置了此种拦截方式;
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值