实现方案
在请求control时加一个前置拦截器,在preHandle中得到HandlerMethod,判断请求的Controller的method的返回类型,
以及请求的Controller方法是否使用的@RestController或者@ResponBody注解。若满足以上条件则抛出异常时,
应该以json格式的报错信息,否则返回错误页面。
写一个拦截器类
/**
* 判断Controller的返回类型,是json还是view
*/
@Component
public class MyExceptionPreHandleInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (!(handler instanceof HandlerMethod)) {
return true;
}
//默认设置为页面返回模式
request.setAttribute("my_return_is_view", true);
if(hm.getBeanType().isAnnotationPresent(RestController.class)) {
//有RestController的类注解的类里面的method一定是返回json
request.setAttribute("my_return_is_view", false);
}else{
Method method = hm.getMethod();
if (method.isAnnotationPresent(ResponseBody.class)) {
//有ResponseBody的类注解的方法一定是返回json
request.setAttribute("my_return_is_view", false);
}
}
return true;
}
}
SpringBoot配置该拦截器
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
MyExceptionPreHandleInterceptor ex;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 全局异常处理 前置处理拦截器
registry.addInterceptor(ex).addPathPatterns("/**");
}
}
全局的异常处理类
@ControllerAdvice
public class MyBaseControllerAdvice {
private Logger log = LoggerFactory.getLogger(this.getClass());
@ExceptionHandler
public Object handleException(Exception e, HttpServletRequest request, HttpServletResponse response) throws Exception {
//获取拦截器判断的返回结果类型
Object o = request.getAttribute("my_return_is_view");
if (o == null) {
log.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;
}
}
}