SpringBoot之Filter/HandlerInterceptor 中注入service为null解决方案
今天有人问我怎么实现访问项目的时候,把一些请求存下来,我一听,我就说 拦截器啊,然后自己回家也试了试,发现注入service的时候会报null,因为 filter不能直接注入 spring容器里面的对象,然后我就自己从spring 容器里面去取了。代码如下1.Filter 配置@Configurationpublic class UrlFilter implements Filter ...
今天有人问我怎么实现访问项目的时候,把一些请求存下来,我一听,我就说 拦截器啊,然后自己回家也试了试,发现注入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方法获取的就是这张表的数据,所以全都出来了。
更多推荐
所有评论(0)