我有一个用于每个异常的全局异常处理程序,我希望它处理不同的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);
}
我找到了解决问题的方法。
-
我错误地在 AbstractHandlerExceptionResolver 中混合了@ControllerAdvice和@ExceptionHandler。它们是处理异常的不同方法。查看此链接
所以我把@ControllerAdvice换成了@Component,@ExceptionHandler去掉了。现在,方法处理程序在处理程序参数中返回
-
我使用了这种方法:
私有静态布尔值 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;
}