文章转载知乎
SpringBoot全局异常处理后返回时,区分方法返回类型json还是页面
在使用SpringBoot 配置全局异常的时候。发现大多数都是直接返回的json, 如果是使用前端分离的情况下自然没有问题。但是如果还没有分离。使用模板引擎的话。返回页面的请求报错了就会出现 页面上显示json 字符串。
实现思路
配置一个全局拦截器。 在进行访问页面之前配置一个变量。这个变量用于判断访问的这个接口方法返回的是页面还是 json 串。
拦截器
@Component
public class ExceptionPreHandleInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
if (!(handler instanceof HandlerMethod)){
return true;
}
HandlerMethod hm = (HandlerMethod) handler;
Method method = hm.getMethod();
// 判断返回值是否为字符串
boolean isString = method.getReturnType().equals(String.class);
// 判断方法是否使用 @ResponseBody
boolean isResonseBody = !method.isAnnotationPresent(ResponseBody.class);
// 判断方法是否使用 @RestController注解
boolean isRestController = !hm.getBeanType().isAnnotationPresent(RestController.class);
request.setAttribute("method_return_is_view",isString && isResonseBody && isRestController);
return true;
}
}
配置拦截器添加到SpringBoot 应用中
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private ExceptionPreHandleInterceptor preHandleInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(preHandleInterceptor).addPathPatterns("/**");
}
}
全局异常处理器
@ControllerAdvice
public class GlobalExceptionControllerAdvice {
@ExceptionHandler(value = Exception.class)
public Object globalExceptionHandler(Exception e, HttpServletRequest request, HttpServletResponse response){
Object o = request.getAttribute("method_return_is_view");
response.setStatus(500);
Boolean isView = (Boolean) o;
if (isView){
ModelAndView modelAndView = new ModelAndView("/error");//配置需要跳转的Controller方法
request.setAttribute("message", "系统异常");
return modelAndView;
}else {
ModelAndView modelAndView = new ModelAndView(new MappingJackson2JsonView());
modelAndView.addObject("code", response.getStatus());
modelAndView.addObject("message", "系统异常");
modelAndView.addObject("data", "");
return modelAndView;
}
}
}
创建请求/
@Controller
public class ExceptionController {
@GetMapping(value = "test")
@ResponseBody
public String test(){
String s = null;
s.charAt(0);
return "test";
}
@GetMapping(value = "test2")
public String test2(){
String s = null;
s.charAt(0);
return "test";
}
}