如何在 Spring 全局异常处理程序的 JSON 方法中处理不同的异常



我有一个用于每个异常的全局异常处理程序,我希望它处理不同的JSON方法。但我想保持集中。

@ControllerAdvice
public class GlobalExceptionHandler extends AbstractHandlerExceptionResolver{
    @ExceptionHandler(Exception.class)
    @Override
    protected ModelAndView doResolveException(HttpServletRequest  request, 
                                              HttpServletResponse response,
                                              Object handler, 
                                              Exception ex) {
   // Omitted code like logging, message translation, etc.
    String contentType = response.getContentType();
    //FIXME: This do NOT WORK. contentType will be null
    if(contentType != null && contentType.startsWith(MediaType.APPLICATION_JSON_VALUE)){
            // Add error as a header                                
            modelAndView.setView( new MappingJackson2JsonView() );
    }else{
            // Add error to model   
            modelAndView.setViewName(MyJSPView);                        
    }
}

调试后,我看到内容类型为空,我不能使用它。如何区分这两个调用?为了进行测试,我编写了这对方法:

@RequestMapping(value = "jspTest")
public String jspTest(){
    throw new UserMessageException(ErrorMessages.TESTING_ERROR);
}

@RequestMapping(value = "jsonTest", produces = ContentType.JSON)
@ResponseBody
public String jsonTest(){
    throw new UserMessageException(ErrorMessages.TESTING_ERROR);
}

我找到了解决问题的方法。

  1. 我错误地在 AbstractHandlerExceptionResolver 中混合了@ControllerAdvice和@ExceptionHandler。它们是处理异常的不同方法。查看此链接

    所以我把@ControllerAdvice换成了@Component,@ExceptionHandler去掉了。现在,方法处理程序在处理程序参数中返回

  2. 我使用了这种方法:

私有静态布尔值 isJson(对象处理程序){

if( ! (handler instanceof HandlerMethod)){
    return false;
}
        
RequestMapping mapping =  ((HandlerMethod) handler).getMethodAnnotation(RequestMapping.class);
for(String mimeType : mapping.produces()){
    if( mimeType.indexOf(MediaType.APPLICATION_JSON_VALUE)  != -1 ){
        return true;
    }
}
// Mime types produced does not include  application/json
return false;

}

最新更新