美文网首页
Springboot 拦截器的坑

Springboot 拦截器的坑

作者: 纳米君 | 来源:发表于2019-04-10 17:26 被阅读0次

Springboot1 和 Springboot2 的拦截器实现类是一致的,配置类有些变化。

实现类如下:

@Component
public class LoginInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //判断用户是否登录过
        UserDto userInfo = (UserDto) request.getSession().getAttribute("userInfo");
        if (userInfo == null) {
            //没有登录或session过期跳到登录页面
            response.sendRedirect(request.getContextPath() + "/app/login");
            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 {

    }

}

Springboot1 基于JDK1.7,其配置类继承WebMvcConfigurerAdapter即可。

@Configuration
public class InterceptorConfiguration extends WebMvcConfigurerAdapter {
    @Autowired
    private LoginInterceptor loginInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor).addPathPatterns("/**")
                .excludePathPatterns("/app/login");
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("redirect:/app/login");
        registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
    }

}

Springboot2 基于JDK1.8,WebMvcConfigurerAdapter类已过时,如下:

@Deprecated
public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {

}

由于JDK1.8 接口里面有default关键字的默认方法,实现接口并不强制覆盖这些方法。所以Springboot2 的拦截器配置类实现WebMvcConfigurer接口即可。如下:

@Configuration
public class InterceptorConfiguration implements WebMvcConfigurer {

    @Autowired
    private LoginInterceptor loginInterceptor;

    // 用来注册拦截器,拦截器需要注册才能生效
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // excludePathPatterns 一定要完全匹配,不能是"/login",否则会被拦截
        registry.addInterceptor(loginInterceptor).addPathPatterns("/**")
                .excludePathPatterns("/app/login");

    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        // 设置默认页面跳转
        registry.addViewController("/").setViewName("redirect:/app/login");
        registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
    }
}

但是,百度搜索Springboot2拦截器,还有一种配置方式是继承WebMvcConfigurationSupport类,这时候就有坑了。

当继承WebMvcConfigurationSupport类时,会导致application.propertiesapplication.yml 文件中的配置失效,返回jsp页面时,抛出异常:Could not resolve view with name 'login' in servlet with name 'dispatcherServlet'

If you want to keep Spring Boot MVC features and you want to add additional MVC configuration (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc.
If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.

大概意思是想要使用Spring Boot MVC提供的拦截器、视图控制器等,必须使我们定义的类实现WebMvcConfigurer并加上注解@Configuration,但是不能加@EnableWebMvc

当我们使用@EnableWebMvc,也代表我们放弃了 spring 提供的默认配置。通过EnableWebMvc源码得知,引入了DelegatingWebMvcConfiguration类,而它又继承了WebMvcConfigurationSupport类。

/**
 * Adding this annotation to an {@code @Configuration} class imports the Spring MVC
 * configuration from {@link WebMvcConfigurationSupport}

 * 从上面这句话也可以看出,该注解和 WebMvcConfigurationSupport 类息息相关。
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}

结论:避免使用注解@EnableWebMvcWebMvcConfigurationSupport类。

详情请参考:Spring注解@EnableWebMvc使用坑点解析

相关文章

网友评论

      本文标题:Springboot 拦截器的坑

      本文链接:https://www.haomeiwen.com/subject/dhzniqtx.html