8/16Filter自动注入问题

SpringBoot之Filter/HandlerInterceptor 中注入service为null解决方案

转自https://blog.csdn.net/yali_aini/article/details/83721763
注入service的时候会报null,因为 filter不能直接注入 spring容器里面的对象,然后我就自己从spring 容器里面去取了。代码如下

1.Filter 配置
@Configuration
public class UrlFilter implements Filter {

@Autowired
private UserInfoService userInfoService;

@Bean
public FilterRegistrationBean setBean(){
    FilterRegistrationBean bean = new FilterRegistrationBean();
    bean.setFilter( new UrlFilter() );
    bean.addUrlPatterns("/*");
    System.out.println("注入了 filter");
    return bean;
}

@Override
public void init(FilterConfig filterConfig) throws ServletException {

}

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest)servletRequest;
    String url = request.getRequestURI() ;

    // 获取 servlet上下文
    ServletContext sc = request.getSession().getServletContext();
    // 获取 spring 容器
    AbstractApplicationContext cxt = (AbstractApplicationContext) WebApplicationContextUtils.getWebApplicationContext(sc);
    if(cxt != null && cxt.getBean("userInfoService") != null && userInfoService == null){
        // 取出 userInfoService
        userInfoService = (UserInfoService) cxt.getBean("userInfoService");
    }

    UserInfo userInfo = new UserInfo();
    userInfo.setTitle( url );
    userInfo.setPassword("filter");
    userInfo.setUsername("filter");
    userInfoService.insert(userInfo);

    filterChain.doFilter(servletRequest,servletResponse);
}

@Override
public void destroy() {

}

}
因为这里直接获取不到 spring容器的service,所以我这里直接从spring容器里面去取

2.HandlerInterceptor拦截器实现
我把过滤器的写好了,发给她后,她说他现在用拦截器写的,说不想改了,我想也罢,就用拦截器写把

首先说一下,拦截器和过滤器的一个区别,过滤器不支持  @Autowired 注入,但是 拦截器支持  @Autowired注入的

所以,我们的代码就可以这样写了

拦截器代码:
@Configuration
public class URLHandlerInterceptor extends HandlerInterceptorAdapter {

@Autowired
private UserInfoService userInfoService;

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

    String url = request.getRequestURI() ;

    UserInfo userInfo = new UserInfo();
    userInfo.setTitle( url );
    userInfo.setPassword("handle");
    userInfo.setUsername("handle");
    userInfoService.insert(userInfo);

    // false 前端会显示 200
    // true 前端显示 404
    return true;
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
        throws Exception {
    // 放行
    super.postHandle(request, response, handler, modelAndView);
}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    // 放行
    super.afterCompletion(request, response, handler, ex);
}

}
拦截器配置:(此处重要,这里配置对了,@Autowired才注入的进去)
@Configuration
public class URLHandlerConfig implements WebMvcConfigurer {

@Bean
public URLHandlerInterceptor setBean2(){
    System.out.println("注入了handler");
    return new URLHandlerInterceptor();
}

@Override
public void addInterceptors(InterceptorRegistry registry) {

    // 多个拦截器组成一个拦截器链
    // addPathPatterns 用于添加拦截规则
    // excludePathPatterns 用户排除拦截
    //由于spring boot 2.x依赖的spring 5.x版本,使用spring 5.x时,静态资源也会执行自定义的拦截器
    //所有导致静态资源不可访问的问题
    String [] exculudes = new String[]{"/*.html","/html/**","/js/**","/css/**","/images/**"};
    registry.addInterceptor(setBean2()).addPathPatterns("/**").excludePathPatterns(exculudes);

}

}
此处的  addInterceptors 里面的  registry.addInterceptor() 参数直接写 上面 serBean2() 这样才注入的进去,才是从 spring 容器里面取得

由于spring boot 2.x依赖的spring 5.x版本,使用spring 5.x时,静态资源也会执行自定义的拦截器,所以这里得配置一下排除

3.访问效果:

可以看到,过滤器也执行了,拦截器也执行了,存入了两条数据金数据库了,就是我的访问地址,因为我的getAll方法获取的就是这张表的数据,所以全都出来了。

版权声明:本文为CSDN博主「临窗,听雨声」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yali_aini/article/details/83721763

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值