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

 更新时间:2021年09月17日 11:11:56   作者:sorrow_yc  
这篇文章主要介绍了spring boot中interceptor拦截器未生效的解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

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());
    }

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

相关文章

  • java中JDBC实现往MySQL插入百万级数据的实例代码

    java中JDBC实现往MySQL插入百万级数据的实例代码

    这篇文章主要介绍了java中JDBC实现往MySQL插入百万级数据的实例代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-01-01
  • 详解SpringIOC BeanDeifition

    详解SpringIOC BeanDeifition

    这篇文章主要介绍了SpringIOC BeanDeifition的相关资料,帮助大家更好的理解和学习springioc,感兴趣的朋友可以了解下
    2020-12-12
  • Spring boot项目打包成jar运行的二种方法

    Spring boot项目打包成jar运行的二种方法

    这篇文章主要给大家介绍了关于Spring boot项目打包成jar运行的二种方法,文中通过示例代码介绍的非常详细,对大家学习或者使用spring boot具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-11-11
  • 如何使用IDEA从SVN服务端检出项目

    如何使用IDEA从SVN服务端检出项目

    这篇文章主要介绍了如何使用IDEA从SVN服务端检出项目问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • 解决idea中yml文件图标问题及自动提示失效的情况

    解决idea中yml文件图标问题及自动提示失效的情况

    这篇文章主要介绍了解决idea中yml文件图标问题及自动提示失效的情况,具有很好的价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • 详解前后端分离之Java后端

    详解前后端分离之Java后端

    这篇文章主要介绍了详解前后端分离之Java后端,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • 快速入门HarmonyOS的Java UI框架的教程

    快速入门HarmonyOS的Java UI框架的教程

    这篇文章主要介绍了快速入门HarmonyOS的Java UI框架,本文给大家介绍的非常详细对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • SpringBoot2.0 ZipKin示例代码

    SpringBoot2.0 ZipKin示例代码

    这篇文章主要介绍了SpringBoot2.0 ZipKin示例代码,详细的介绍了什么是ZipKin以及SpringBoot2.0 ZipKin示例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-11-11
  • Java程序的逻辑控制和方法详解

    Java程序的逻辑控制和方法详解

    这篇文章主要介绍了Java程序的逻辑控制和方法详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • SpringBoot+aop实现主从数据库的读写分离操作

    SpringBoot+aop实现主从数据库的读写分离操作

    读写分离的作用是为了缓解写库,也就是主库的压力,但一定要基于数据一致性的原则,就是保证主从库之间的数据一定要一致,这篇文章给大家介绍SpringBoot+aop实现主从数据库的读写分离操作,感兴趣的朋友跟随小编一起看看吧
    2024-03-03

最新评论