最近在写项目时遇到了一个问题,定义了登录拦截器后总会出现明明登陆了却提示未登录的情况!重点来了!!
***每次出现这种情况都是前台数据传过来校验出错导致的***
![在这里插入图片描述](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<String> handleMethodArgumentNotValidException(MethodArgumentNotValidException e , HttpServletRequest request) {
String uri = request.getRequestURI();
Map<String, Object> 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<String> handleMySQLIntegrityConstraintViolationException(MySQLIntegrityConstraintViolationException e , HttpServletRequest request) {
String uri = request.getRequestURI();
Map<String, Object> 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<String> handleException(Exception e , HttpServletRequest request) {
// String uri = request.getRequestURI();
// Map<String, Object> 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了!至此,大功告成!!