关于springboot默认全局异常处理对拦截器的影响

最近在写项目时遇到了一个问题,定义了登录拦截器后总会出现明明登陆了却提示未登录的情况!重点来了!!

***每次出现这种情况都是前台数据传过来校验出错导致的***
![在这里插入图片描述](https://img-blog.csdn.net/20180921181954170?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2JhaWR1XzM4NjA5NzQ0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

于是下了大时间翻遍博客但是都没有想要的答案,静下心思考了下,既然会出现未登录提示,那么一定是再次经过了登陆拦截器,

于是我推测:springboot的默认全局异常拦截器BasicErrorController会对错误的URI进行一个转发,而这个转发到的URI不在我的拦截器excludePathPatterns范围内

这个是原本的排除范围

@Override
	protected void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(loginInterceptor)
				.addPathPatterns("/**")
				.excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**","/register","/login");
		super.addInterceptors(registry);
	}

接下来看下springboot默认全局异常要跳转到的类的URL

@Controller
@RequestMapping("${server.error.path:${error.path:/error}}")
public class BasicErrorController extends AbstractErrorController {

	private final ErrorProperties errorProperties;
..........

解决办法一:

将springboot默认全局异常要跳转的URL屏蔽掉,不再次经过登陆拦截器

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import com.rain.interceptor.LoginInterceptor;

@Configuration
public class MvcInterceptorConfig extends WebMvcConfigurationSupport {

	@Autowired
	private LoginInterceptor loginInterceptor;

	@Override
	protected void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(loginInterceptor)
				.addPathPatterns("/**")
				//重点重点重点重点重点重点看最后一个路径
				.excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**","/register","/login","/**/error");
		super.addInterceptors(registry);
	}

	@Override
	protected void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("swagger-ui.html")
        .addResourceLocations("classpath:/META-INF/resources/");
		registry.addResourceHandler("/webjars/**")
        .addResourceLocations("classpath:/META-INF/resources/webjars/");
		registry.addResourceHandler("classpath:/gen","classpath:application.yml","classpath:logback.xml");
		super.addResourceHandlers(registry);
	}
	
}

解决方法二:

自定义全局拦截器,在springboot默认拦截器之前对其进行拦截就OK了,这种方案也是强力推荐的(这样能更灵活的对不同的异常进行不同的处理,当然也可以直接写一个Excetpion的拦截器,这就是懒人的做法了嘻嘻嘻)

@RestControllerAdvice
public class GExceptionHandler {
	private static Logger logger = LoggerFactory.getLogger(GExceptionHandler.class);
	/**
	 * 参数校验错误
	 * @param e
	 * @param request
	 * @return
	 */
	@ExceptionHandler(MethodArgumentNotValidException.class)
	public R handleMethodArgumentNotValidException(MethodArgumentNotValidException e , HttpServletRequest request) {
		String uri = request.getRequestURI();
		Map content = new HashMap<>();
		content.put("uri", uri);
		String message = e.getBindingResult().getAllErrors().iterator().next().getDefaultMessage();
		content.put("message", message);
		logger.error(e.getMessage(), e);
		return R.errM(content.toString());
	}
	/**
	 * 可能主键插入重复或者其他SQL错误
	 * @param e
	 * @param request
	 * @return
	 */
	@ExceptionHandler(MySQLIntegrityConstraintViolationException.class)
	public R handleMySQLIntegrityConstraintViolationException(MySQLIntegrityConstraintViolationException e , HttpServletRequest request) {
		String uri = request.getRequestURI();
		Map content = new HashMap<>();
		content.put("uri", uri);
		String message = e.iterator().next().getMessage();
		content.put("message", message);
		logger.error(e.getMessage(), e);
		return R.errM(content.toString());
	}
//	@ExceptionHandler(Exception.class)
//	public R handleException(Exception e , HttpServletRequest request) {
//		String uri = request.getRequestURI();
//		Map content = new HashMap<>();
//		content.put("uri", uri);
//		content.put("message", "异常");
//		logger.error(e.getMessage(), e);
//		return R.errM(content.toString());
//	}
}

=============================================================================

这样在遇到对应的异常时拦截到直接return,就不会再经过springboot默认拦截器了

总结:springboot默认异常处理会对你访问的URL做一个转发到自带的异常处理类BasicErrorController,以这一点出发就OK了!至此,大功告成!!

你可能感兴趣的:(java,springboot,登陆拦截器)