spring boot中interceptor拦截器未生效的解决

目录
  • interceptor拦截器未生效
    • 开始用的spring boot版本为1.5.6
    • 解决方案
  • HandlerInterceptor实现登录失效拦截等
    • 首先写一个实现HandlerInterceptor的类
    • 然后把这个拦截器注册到spring中

interceptor拦截器未生效

搭建项目时发现拦截器未生效

开始用的spring boot版本为1.5.6

代码如下:

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter{
 @Autowired
 private TimeInterceptor timeInterceptor;
 @Override
 public void addInterceptors(InterceptorRegistry registry) {
  registry.addInterceptor(this.timeInterceptor);
  super.addInterceptors(registry);
 }
}
@Component
public class RequestParamInfoIntorceptor extends HandlerInterceptorAdapter {
   private Logger logger = LoggerFactory.getLogger(RequestParamInfoIntorceptor.class);
     @Override
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
             throws Exception {
         try {
             if (handler instanceof HandlerMethod) {
                 HandlerMethod handlerMethod = (HandlerMethod) handler;
                 String beanName = handlerMethod.getBean().getClass().toString();//类
                 String methodName = handlerMethod.getMethod().getName();//方法名称
                 if(methodName.equals("error") || methodName.equals("success")) {
                     return super.preHandle(request, response, handler);
                 }
                 String uri = request.getRequestURI();//请求路径
                 String remoteAddr = getIpAddr(request);//ip
                 String method = request.getMethod(); //请求方式
                 Map<String,String[]> pramMap = request.getParameterMap();
                 StringBuffer sbf = new StringBuffer();
                 int count = 0;
                 String forCunt = "";
                 for(Map.Entry<String, String[]> entry:pramMap.entrySet()){
                     forCunt = "[" + count + "]" + " : " ;
                     sbf.append( "paramName" + forCunt + entry.getKey() + " - "+ "paramValue" +
                             forCunt + request.getParameter(entry.getKey()) + "\n");
                     count ++;
                 }
                 logger.info(" { beanName : " + beanName + " | " + "methodName : " + methodName + " | " + "uri : "
                         + uri + " | " + "remoteAddr : " + remoteAddr + " | " + "requestMethod : " +
                         method + "\n" + "param : " + sbf + "}");
             }
         } catch (Exception e) {
             //出错
             logger.error(e.toString());
         }
         return super.preHandle(request, response, handler);
     }
     //获取客户端IP
     private String getIpAddr(HttpServletRequest request) {
         String ip = request.getHeader("x-forwarded-for");
         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
             ip = request.getHeader("Proxy-Client-IP");
         }
         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
             ip = request.getHeader("WL-Proxy-Client-IP");
         }
         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
             ip = request.getRemoteAddr();
         }
         return ip;
     }
}

开始以为是版本问题,后升级为2.1.1,WebConfig改为实现WebMvcConfigurer,代码如下

@Configuration
@Component
public class WebConfig implements WebMvcConfigurer{
 @Autowired
 private RequestParamInfoIntorceptor requestParamInfoIntorceptor;

 @Override
 public void addInterceptors(InterceptorRegistry registry) {
  registry.addInterceptor(this.requestParamInfoIntorceptor).addPathPatterns("/**");
 }
}

验证后还是不行,继续排查后发现,在添加版本控制时,有配置类继承了WebMvcConfigurationSupport,查询WebMvcConfigurationSupport源码发现其中有拦截器注册方法addInterceptors(InterceptorRegistry registry),所以在版本控制配置类中重写此方法添加拦截器,拦截器生效,问题解决。

解决方案

代码如下:

@Configuration
public class ApiConfig extends WebMvcConfigurationSupport {
 @Autowired
 private RequestParamInfoIntorceptor requestParamInfoIntorceptor;

 @Override
 protected void addInterceptors(InterceptorRegistry registry) {
  registry.addInterceptor(this.requestParamInfoIntorceptor).addPathPatterns("/**");
  super.addInterceptors(registry);
 }
}

HandlerInterceptor实现登录失效拦截等

首先写一个实现HandlerInterceptor的类

代码如下:

public class SessionInterceptor implements HandlerInterceptor {
    @Autowired
    RedisTemplate<String, String> redisTemplate;
    //private static String LOGIN_CODE = "/user/no_loginPage?Landingcode=" + UserResourcesHelper.LANDINGCODE_106;// 登录地址及code信息
    //private static String LOGIN_CODE = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxd11f95277f85e24b&redirect_uri=&response_type=code&scope=snsapi_userinfo&state=1234#wechat_redirect";
    protected List<String> patterns = new ArrayList<String>(Arrays.asList(".*?/.*/no_.*?", "/", "/error"));
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        // 一些不需要过滤的方法
        String url = request.getRequestURI();
        if (isInclude(url) == true)
            return true;
        // 权限校验
        Cookie cookie = getCookieByName(request, UserResourcesHelper.COOKIE_TOKEN_NAME);
        String user = null;
        if (cookie != null && !cookie.getValue().equals("")) {
            user = redisTemplate.opsForValue().get(RedisKeyConstant.USER_WEB_TOKEN + cookie.getValue());
        }
        if (cookie == null || user == null) {// 判断用户是否经过了授权
            // 判断是否是AJAX访问
            if (request.getHeader("x-requested-with") != null
                    && request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")) {
                response.setHeader("sessionstatus", "timeout");
                response.setStatus(403);
                return false;
            } else {
                response.sendRedirect(request.getContextPath()+"/home/no_index_toLoginSkip");
                //response.sendRedirect(request.getContextPath() +UserResourcesHelper.LOGIN_URL); // 非AJAX访问,页面跳转
                //response.sendRedirect(request.getContextPath() +"https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxd11f95277f85e24b&redirect_uri="+URLEncoder.encode("http://m.hobay.cn/user/no_loginPage", "utf-8")+"&response_type=code&scope=snsapi_base&state=123#wechat_redirect"); // 非AJAX访问,页面跳转
                return false;
            }
        }
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
    }
    private boolean isInclude(String url) {
        for (String pattern : patterns) {
            if (Pattern.matches(pattern, url)) {
                return true;
            }
        }
        return false;
    }
    /**
     * 根据名字获取cookie
     *
     * @param request
     * @param name
     *            cookie名字
     * @return
     */
    private static Cookie getCookieByName(HttpServletRequest request, String name) {
        Map<String, Cookie> cookieMap = ReadCookieMap(request);
        if (cookieMap.containsKey(name)) {
            Cookie cookie = (Cookie) cookieMap.get(name);
            return cookie;
        } else {
            return null;
        }
    }
    /**
     * 将cookie封装到Map里面
     *
     * @param request
     * @return
     */
    private static Map<String, Cookie> ReadCookieMap(HttpServletRequest request) {
        Map<String, Cookie> cookieMap = new HashMap<String, Cookie>();
        Cookie[] cookies = request.getCookies();
        if (null != cookies) {
            for (Cookie cookie : cookies) {
                cookieMap.put(cookie.getName(), cookie);
            }
        }
        return cookieMap;
    }

然后把这个拦截器注册到spring中

代码如下:

@EnableWebMvc
@Configuration
public class WebConfig  extends WebMvcConfigurerAdapter{
     @Bean
     SessionInterceptor sessioninterceptor() {
         return new SessionInterceptor();
    }
    /**
     * 配置拦截器
     * @author yuqingquan
     * @param registry
     */
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(sessioninterceptor());
    }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • spring boot拦截器注入不了java bean的原因

    一.如何实现拦截器 在Spring Boot项目中,拦截器经常被用来做登陆验证,日志记录等操作.拦截器是Spring提供的,所以可以将拦截器注成bean,由IOC容器来管理.实现拦截器的方式很简单,主要由以下两个步骤: 自定义拦截器类实现HandlerInterceptor接口 自定义WebMvc配置类实现WebMvcConfigurer接口,添加自定义拦截器类 简要实现代码如下: 自定义拦截器 LoginInterceptor: public class LoginInterceptor im

  • SpringBoot之HandlerInterceptor拦截器的使用详解

    前言 平常项目开发过程中,会遇到登录拦截,权限校验,参数处理,防重复提交等问题,那拦截器就能帮我们统一处理这些问题. 一.实现方式 1.1 自定义拦截器 自定义拦截器,即拦截器的实现类,一般有两种自定义方式: 定义一个类,实现org.springframework.web.servlet.HandlerInterceptor接口. 定义一个类,继承已实现了HandlerInterceptor接口的类,例如org.springframework.web.servlet.handler.Handle

  • springboot Interceptor拦截器excludePathPatterns忽略失效

    springboot Interceptor拦截器excludePathPatterns忽略失效 excludePathPatterns方法是排除访问路径,但是当你排除的url路径在项目中并不存在的时候,springboot会将路径编程/error,从而无法进行排除. 例如下面代码: registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/login&q

  • springboot拦截器Interceptor的使用,你都了解吗

    springmvc 中的拦截器可以对请求进行判别, 在请求到达控制器之前, 把非法的请求给拦截掉 下面来说一说, 它在springboot中的使用 拦截器是可以有多个的, 对不同的 url 进行拦截 我们这个例子设想的是, 如果用户登录过, 就会用户设置一个 session , 如果session中 有user 的信息,就说明用户是登录过的 1.我们先创建一个 User 的实例对象 domain public class User { private Integer id; private St

  • 解决Springboot @WebFilter拦截器未生效问题

    问题描述 @WebFilter(filterName = "ssoFilter",urlPatterns = "/*") 未生效拦截器 解决方法 在springboot启动类上添加 @ServletComponentScan(basePackages = "full.package.path") 路径替换为@WebFilter所在包 补充知识:在spring boot中使用@WebFilter配置filter(包括排除URL) 我就废话不多说了,

  • spring boot中interceptor拦截器未生效的解决

    目录 interceptor拦截器未生效 开始用的spring boot版本为1.5.6 解决方案 HandlerInterceptor实现登录失效拦截等 首先写一个实现HandlerInterceptor的类 然后把这个拦截器注册到spring中 interceptor拦截器未生效 搭建项目时发现拦截器未生效 开始用的spring boot版本为1.5.6 代码如下: @Configuration public class WebConfig extends WebMvcConfigurerA

  • Spring MVC中自定义拦截器的实例讲解

    1. 引言 拦截器(Interceptor)实现对每一个请求处理前后进行相关的业务处理,类似于Servlet的Filter. 我们可以让普通的Bean实现HandlerIntercpetor接口或继承HandlerInterceptorAdapter类来实现自定义拦截器. 通过重写WebMvcConfigurerAdapter的addIntercetors方法来注册一个计算每一次请求的处理时间的拦截器. 2. 自定义拦截器的实现 2.1 定义拦截器 新建LogInterceptor类,并继承Ha

  • Spring Boot如何利用拦截器加缓存完成接口防刷操作

    目录 为什么需要接口防刷 技术解析 主要代码 测试结果 总结 为什么需要接口防刷 为了减缓服务器压力,将服务器资源留待给有价值的请求,防止恶意访问,一般的程序都会有接口防刷设置,接下来介绍一种简单灵活的接口防刷操作 技术解析 主要采用的技术还是拦截+缓存,我们可以通过自定义注解,将需要防刷的接口给标记出来管理,利用缓存统计指定时间区间里,具体的某个ip访问某个接口的频率,如果超过某个阈值,就让他进一会儿小黑屋,到期自动解放 主要代码 前置环境搭建,Spring Boot项目,引入Web和Redi

  • spring boot security设置忽略地址不生效的解决

    spring boot security设置忽略地址不生效 最近在试下微服务改造,出现这样一个问题所有请求都经过spring cloud gateway进行认证授权后再访问后端数据方服务,但有些需要合作机构回调,由于进行了security认证,最终的方案是对回调地址进行忽略auth认证. 最终security主要代码如下: @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityCon

  • spring boot如何添加拦截器

    构建一个spring boot项目. 添加拦截器需要添加一个configuration @Configuration @ComponentScan(basePackageClasses = Application.class, useDefaultFilters = true) public class ServletContextConfig extends WebMvcConfigurationSupport { 为了方便扫描位置,我们可以写一个接口或者入口类Application放置于最外

  • Spring boot如何基于拦截器实现访问权限限制

    遇到一个需求是:要为用户设置不同的菜单.数据访问权限.对于一些特定类型的数据,有的用户可以看有的用户则不可以.一开始没有太多思路,后来一想是不是可以把"特定类型"这个参数通过@PathVariable注解加到路径上,这样就可以通过拦截器拦截后,校验此用户是否可以访问这个路径(类型)下的数据了. 话不多说,以下为具体实践 拦截器配置类 @Configuration public class UserInterceptorConfig { //为了保证IDbnetUserService提前

  • Spring Boot项目中定制拦截器的方法详解

    这篇文章主要介绍了Spring Boot项目中定制拦截器的方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Servlet 过滤器属于Servlet API,和Spring关系不大.除了使用过滤器包装web请求,Spring MVC还提供HandlerInterceptor(拦截器)工具.根据文档,HandlerInterceptor的功能跟过滤器类似,但拦截器提供更精细的控制能力:在request被响应之前.request被响应之后.视

  • 详解SpringMVC中使用Interceptor拦截器

    SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那样子判断当前时间是否是购票时间.  一.定义Interceptor实现类 SpringMVC 中的Interceptor 拦截请求是通过HandlerInterceptor 来实现的.在SpringMVC 中定义一个Interceptor 非常简单,主要有两种方式,第一种方式是要定义的Interce

  • Spring中自定义拦截器的使用

    1.创建自定义拦截器类(UserTokenInterceptor)并实现HandlerInterceptor 接口,再重写方法,代码如下: public class UserTokenInterceptor implements HandlerInterceptor { /** * @description 访问Controller之前执行 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletR

随机推荐