全局异常捕获和非法访问拦截
全局异常捕获
spring mvc:
自定义一个全局异常类实现HadlerExceptionResovler接口类
重新里面的方法
public class GlobalException2 implements HandlerExceptionResolver {
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response,
Object handler, Exception e) {
ModelAndView mv=new ModelAndView();
mv.setViewName("error");
mv.addObject("msg","系统异常");
mv.addObject("code",500);
if (handler instanceof HandlerMethod){
//
HandlerMethod handlerMethod=(HandlerMethod)handler;
ResponseBody declaredAnnotation = handlerMethod.getMethod().getDeclaredAnnotation(ResponseBody.class);
if (declaredAnnotation==null){//返回视图
//判断异常类型
if (e instanceof ParamsException){
mv.addObject("msg",((ParamsException) e).getMsg());
mv.addObject("code",((ParamsException) e).getCode());
}
return mv;
}else{//返回json数据
ResultInfo resultInfo=new ResultInfo();
resultInfo.setCode(300);
resultInfo.setMsg("系统异常");
if (e instanceof ParamsException){
resultInfo.setMsg(((ParamsException) e).getMsg());
resultInfo.setCode(((ParamsException) e).getCode());
}
response.setContentType("application/json;charset=utf-8");
PrintWriter writer=null;
try {
writer = response.getWriter();
writer.write(JSON.toJSONString(resultInfo));
writer.flush();
} catch (IOException ex) {
ex.printStackTrace();
}finally {
if (writer!=null){
writer.close();
}
}
return null;
}
}
return mv;
}
}
spring boot新方式:
自定义全局异常类,配上@ControllerAdvice注解
在方法上配上@ExceptionHandler注解表明异常类型
@ControllerAdvice
public class GlobalExceptionResolver {
@ExceptionHandler(ParamsException.class)
@ResponseBody
public ResultInfo paramsException(){
ResultInfo resultInfo = new ResultInfo();
resultInfo.setCode(300);
resultInfo.setMsg("参数错误");
return resultInfo;
}
@ExceptionHandler(Exception.class)
@ResponseBody
public ResultInfo exception(){
ResultInfo resultInfo = new ResultInfo();
resultInfo.setCode(500);
resultInfo.setMsg("默认异常");
return resultInfo;
}
}
非法访问拦截
定义拦截器
自定义一个拦截的类继承HandlerInterceptorAdapter,重写想去重写的方法
可以将拦截的信息直接抛出异常,在全局异常捕获的地方进行统一处理。
public class NologinInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
boolean falg=true;//比如用户未登录就拦截,然后在全局异常中判断是否是这个异常
if (falg){
throw new NoLoginException();
}
return true;
}
}
拦截器生效配置
@Configuration+@Bean bean下面的
@Configuration
public class mvcConfig implements WebMvcConfigurer {
@Bean
private NoLoginInterceptor createInterceptor(){
return new NoLoginInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(createInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/index","/user/login","/css/**","/images/**","/js/**","/lib/**");
}
}
@Configuration注解,表明该类是配置类,可以使用自动扫描
@bean注解下方法不要定义为final,private,static,因为那样无法生成代理。就跟@Component+@Bean一样了
@Component+@Bean
Component里面的@Bean之间的引用只是普通的方法调用,
Configuration里面的@Bean之间的引用却是使用AOP做了增强
Configuration实际是用cglib生成了它的一个代理类,
而Component就是普通的new出来的一个bean