SpringBoot项目使用拦截器出现的坑

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_30576089/article/details/102703841

使用WebMvcConfigurationSupport 解决乱码问题后出现的坑*

@Configuration
//@EnableWebMvc
public class MvcInterceptorConfig extends WebMvcConfigurationSupport {
    @Autowired
    private LoginInterceptor loginInterceptor;
    //解决中文乱码问题
    @Bean
    public HttpMessageConverter<String> responseBodyConverter() {
        StringHttpMessageConverter converter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
        return converter;
    }
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        super.configureMessageConverters(converters);
        converters.add(responseBodyConverter());
    }
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorPathExtension(false);
    }
    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        // 多个拦截器组成一个拦截器链
        // addPathPatterns 用于添加拦截规则,/**表示拦截所有请求
        // excludePathPatterns 用户排除拦截
//        registry.addInterceptor(loginInterceptor).addPathPatterns("/**")
//                .excludePathPatterns("/stuInfo/getAllStuInfoA","/account/register");
//       registry.addInterceptor(loginInterceptor).addPathPatterns("/**").excludePathPatterns("/productOrder/createProductOrder");  registry.addInterceptor(loginInterceptor).addPathPatterns("/**").excludePathPatterns("/productOrder/createProductOrder","/error");
        super.addInterceptors(registry);
    }
    // 如果不加,则静态资源会被拦截,导致访问不到静态资源
//    @Override
//    protected void addResourceHandlers(ResourceHandlerRegistry registry){
//        registry.addResourceHandler("/**")
//                .addResourceLocations("classpath:/META-INF/resources/")
//                .addResourceLocations("classpath:/resources/")
//                .addResourceLocations("classpath:/static/")
//                .addResourceLocations("classpath:/public/");
//        super.addResourceHandlers(registry);
//    }
}

由于StringHttpMessageConverter 会使用 spring.http.encoding.charset 配置, 默认编码为:ISO-8859-1 而我们其他地方一般用的是UTF-8,所以会造成乱码,但是通过上面的代码我们设置成了UTF-8的编码格式解决了乱码的问题,但是又有一个新的问题产生,会出现其他错误导致拦截器跳转到/error中去,试了好久也没找到原因,后面另辟蹊径采用WebMvcConfigurer

@Configuration
public class WebConfigurer implements WebMvcConfigurer {
    @Autowired
    LoginInterceptor loginInterceptor;
     @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowCredentials(true)
                .allowedMethods("GET", "POST", "DELETE", "PUT","PATCH")
                .maxAge(3600);
    }
        @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //登录拦截的管理器
        InterceptorRegistration registration = registry.addInterceptor(loginInterceptor);     //拦截的对象会进入这个类中进行判断
        registration.addPathPatterns("/**");                    //所有路径都被拦截
        registration.excludePathPatterns("/productOrder/ebusinessOrder","/error");       //添加不拦截路径
//        super.addInterceptors(registry);


//        //权限拦截的管理器
//        InterceptorRegistration registration1 = registry.addInterceptor(rightsInterceptor);
//        registration1.addPathPatterns("/**");                    //所有路径都被拦截
 //        registration1.excludePathPatterns("/","/login","/error","/static/**","/logout");       //添加不拦截路径
    }
    }

虽没有乱码的问题,但是使用自定义拦截器时跨域相关配置就会失效
原因是请求经过的先后顺序问题,当请求到来时会先进入拦截器中,而不是进入Mapping映射中,所以返回的头信息中并没有配置的跨域信息。浏览器就会报跨域异常。

解决方法:使用CorsFilter过滤器配合

  private CorsConfiguration addcorsConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        List<String> list = new ArrayList<>();
        list.add("*");
        corsConfiguration.setAllowedOrigins(list);
    /*
    // 请求常用的三种配置,*代表允许所有,当时你也可以自定义属性(比如header只能带什么,只能是post方式等等)
    */
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        return corsConfiguration;
    }
    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", addcorsConfig());
        return new CorsFilter(source);
    }

所以最终的代码是:

@Configuration
public class WebConfigurer implements WebMvcConfigurer {
    @Autowired
    LoginInterceptor loginInterceptor;
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowCredentials(true)
                .allowedMethods("GET", "POST", "DELETE", "PUT","PATCH")
                .maxAge(3600);
    }
    private CorsConfiguration addcorsConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        List<String> list = new ArrayList<>();
        list.add("*");
        corsConfiguration.setAllowedOrigins(list);
    /*
    // 请求常用的三种配置,*代表允许所有,当时你也可以自定义属性(比如header只能带什么,只能是post方式等等)
    */
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        return corsConfiguration;
    }
    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", addcorsConfig());
        return new CorsFilter(source);
    }
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //登录拦截的管理器
        InterceptorRegistration registration = registry.addInterceptor(loginInterceptor);     //拦截的对象会进入这个类中进行判断
        registration.addPathPatterns("/**");                    //所有路径都被拦截
        registration.excludePathPatterns("/productOrder/ebusinessOrder","/error");       //添加不拦截路径
//        super.addInterceptors(registry);


//        //权限拦截的管理器
//        InterceptorRegistration registration1 = registry.addInterceptor(rightsInterceptor);
//        registration1.addPathPatterns("/**");                    //所有路径都被拦截
//        registration1.excludePathPatterns("/","/login","/error","/static/**","/logout");       //添加不拦截路径
    }
}

以上就是我在使用拦截器碰到的坑,如有遇到其他的坑,望各位大神不吝赐教!!!!!

猜你喜欢

转载自blog.csdn.net/qq_30576089/article/details/102703841