关于springboot:springBoot-配置拦截器

8次阅读

共计 5980 个字符,预计需要花费 15 分钟才能阅读完成。

springBoot 配置拦截器

如何配置拦截器
拦截器设置容易呈现的问题
如何勾销拦挡操作
实例:登录验证

如何配置拦截器

step1: 自定义拦截器

/**
 * 自定义拦截器
 */
public class MyInterceptor implements HandlerInterceptor {private static final Logger logger = LoggerFactory.getLogger(MyInterceptor.class);

    /**
     * 在申请匹配 controller 之前执行,返回 true 才行进行下一步
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {return false;}

    /**
     * 曾经执行完 controller 了,然而还没有进入视图渲染
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { }

    /**
     * 视图也渲染完了,此时我能够做一些清理工作了
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}}

step2:配置拦截器

@Configuration
public class MyInterceptorConfig extends WebMvcConfigurationSupport {

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**"); // 拦挡所有内容:/** 拦挡局部内容:/admin/**
        super.addInterceptors(registry);
    }
}

拦截器设置容易呈现的问题

动态资源被拦挡

MyInterceptorConfig 继承 WebMvcConfigurationSupport 类时,会导致 resources/static 下的动态资源也被拦挡,如果咱们不想动态资源被拦挡,能够尝试以下两种办法。

/**
* 在 MyInterceptorConfig 中重写 addResourceHandlers 办法,从新指定动态资源
* 举荐在前后端拆散时应用,后盾不须要拜访动态资源
*
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
   super.addResourceHandlers(registry);
}
/**
 * 将 MyInterceptorConfig 类由继承 WebMvcConfigurationSupport 改为实现 WebMvcConfigurer
 * 举荐在非前后端拆散时应用,后盾须要拜访动态资源
 *
 */
@Configuration
public class MyInterceptorConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**"); // 拦挡所有内容:/** 拦挡局部内容:/admin/**
    }
}

如何勾销拦挡操作

step1:自定义注解

/**
 * 自定义注解用来指定某个办法不必拦挡
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UnInterception {}

step2:批改拦截器 MyInterceptor 中的 preHandle 办法

/**
 * 在申请匹配 controller 之前执行
 * @param request
 * @param response
 * @param handler
 * @return
 * @throws Exception
 */
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {UnInterception unInterception = method.getAnnotation(UnInterception.class);
    if(null != unInterception) {logger.info("不须要拦挡,能够执行");
        return true;
    }

    // 返回 true 才会执行办法,返回 false 不会执行
    return false;
}

step3:在不须要拦挡的 controller 上加上 UnInterception 注解

@Controller
@RequestMapping("/interceptor")
public class InterceptorController {

    @UnInterception
    @RequestMapping("/test")
    public String test() {return "hello";}
}

实例:登录验证

用拦截器实现一个登录验证性能

step1:自定义拦截器

import com.kimmel.course13.annotation.UnInterception;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * 自定义拦截器
 */
public class MyInterceptor implements HandlerInterceptor {private static final Logger logger = LoggerFactory.getLogger(MyInterceptor.class);

    /**
     * 在申请匹配 controller 之前执行
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        String methodName = method.getName();

        // 判断用户有没有登录,个别登录之后的用户都有一个对应的 token
        UnInterception unInterception = method.getAnnotation(UnInterception.class);
        String token = request.getParameter("token");
        if (null == token || "".equals(token)) {logger.info("用户未登录,没有权限执行 {} 请登录", methodName);
            return false;
        }

        // 返回 true 才会执行办法,返回 false 不会执行
        return true;
    }

    /**
     * 曾经执行完 controller 了,然而还没有进入视图渲染
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        String methodName = method.getName();
        logger.info("曾经执行完 {} 了,然而还没有进入视图渲染", methodName);
    }

    /**
     * 视图也渲染完了,此时我能够做一些清理工作了
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {logger.info("视图也渲染完了,此时我能够做一些清理工作了");
    }
}

step2:配置拦截器

import com.kimmel.course13.Interceptor.MyInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

@Configuration
public class MyInterceptorConfig extends WebMvcConfigurationSupport {

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**"); // 拦挡所有内容:/** 拦挡局部内容:/admin/**
        super.addInterceptors(registry);
    }

    /**
     * 发现如果继承了 WebMvcConfigurationSupport,则在 yml 中配置的相干内容会生效。须要从新指定动态资源
     *
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
        registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
        super.addResourceHandlers(registry);
    }
}

step3:自定义测试 controller

@Controller
@RequestMapping("/interceptor")
public class InterceptorController {@RequestMapping("/test")
    public String test() {return "hello";}
}

step4:测试

进入浏览器,输出 http://localhost:8080/interceptor/test
后果:无奈进入,日志:用户未登录,没有权限执行 test 请登录
进入浏览器,输出 http://localhost:8080/interceptor/test?token=1
后果:胜利进入 hello.html
正文完
 0