SpringBoot全局异常处理后返回时,区分方法返回类型json还是页面

2,797 阅读1分钟

在处理异常时,我们需要对API请求抛出的异常时,我们要以JSON的形式返回错误信息。而在请求页面时报错的话,我们需要在跳转到相应的报错页面进行友好提示。

实现思路

在进入全局异常处理器之前,加一个拦截器,在preHandle中取得HandlerMethod,判断请求的Controller方法的返回类型,以及请求的Controller方法是否使用的@RestController或者@ResponBody注解。若满足以上条件则抛出异常时,应该返回json格式的报错信息,否则返回相应的错误页面。

拦截器

/**
 * 判断Controller是返回json还是页面的拦截器,为统一异常处理返回结果做判断依据
 */
@Component
public class ExceptionPreHandleInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod hm = (HandlerMethod) handler;
        Method method = hm.getMethod();
        //Controller方法返回值是否为字符串
        boolean b1 = method.getReturnType().equals(String.class);
        //Controller方法是否使用@ResponseBody注解
        boolean b2 = !method.isAnnotationPresent(ResponseBody.class);
         //Controller是否使用@RestController注解
        boolean b3 = !hm.getBeanType().isAnnotationPresent(RestController.class);
        request.setAttribute("method_return_is_view", b1 && b2 && b3);

        return true;
    }
}

将该拦截器配置到SpringBoot中

@Configuration
public class WebConfig implements WebMvcConfigurer {
	 
		@Autowired
		ExceptionPreHandleInterceptor exceptionPreHandleInterceptor;

		@Override
		public void addInterceptors(InterceptorRegistry registry) {
			// 全局异常处理 前置处理拦截器
			registry.addInterceptor(exceptionPreHandleInterceptor).addPathPatterns("/**");
		}
}

全局异常处理器

@ControllerAdvice
public class BaseControllerAdvice {

    private Logger logger = LoggerFactory.getLogger(this.getClass());


    @ExceptionHandler
    public Object handleException(Exception e, HttpServletRequest request, HttpServletResponse response) throws Exception {
    //获取拦截器判断的返回结果类型
        Object o = request.getAttribute("method_return_is_view");
        if (o == null) {
            logger.error("", e);
            throw e;
        }
        //是否是html/text
        boolean isView = (Boolean) o;
 
        //返回页面
        if (isView) {
           ModelAndView  modelAndView = new ModelAndView("/error");//配置需要跳转的Controller方法
            request.setAttribute("message", "系统异常");
            return modelAndView;
        } else {//返回json
           ModelAndView  modelAndView = new ModelAndView(new MappingJackson2JsonView());
            modelAndView.addObject("code", "500");
            modelAndView.addObject("message", "系统异常");
            modelAndView.addObject("data", );
            return modelAndView;
        }
    }
}

原文地址: springboot全局异常处理ControllerAdvice示例区分方法返回类型json还是页面