版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
使用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"); //添加不拦截路径
}
}
以上就是我在使用拦截器碰到的坑,如有遇到其他的坑,望各位大神不吝赐教!!!!!