Spring MVC ExceptionHandler用于restful和normal

时间:2015-08-18 11:11:43

标签: spring-mvc exception-handling spring-rest

我想处理normal和rest / ajax请求的异常。这是我的代码,

@ControllerAdvice
public class MyExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ModelAndView handleCustomException(Exception ex) {

        ModelAndView model = new ModelAndView("error");
        model.addObject("errMsg", ex.getMessage());
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        ex.printStackTrace(pw);
        sw.toString();
        model.addObject("errTrace", sw);
        return model;

    }

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public String handleAjaxException(Exception ex) {
        JSONObject model = new JSONObject();
        model.put("status", "error");
        model.put("errMsg", ex.getMessage());
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        ex.printStackTrace(pw);
        sw.toString();
        model.put("errTrace", sw);

        return model.toString();
    }
}

这会给我一个错误,因为我不能有两次@ExceptionHandler(Exception.class)。那可能是什么解决方案?

4 个答案:

答案 0 :(得分:4)

查看@ControllerAdvice的配置: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/ControllerAdvice.html

所以你可以创建两个类(错误处理程序)并指定注释/ basePackages / assignibaleTypes

例如对于REST(ajax),为控制器使用@RestController注释,你可以处理这样的错误:

@ControllerAdvice(annotations = RestController.class)
public class MyExceptionHandler {

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public String handleAjaxException(Exception ex) {
        ...
    }
}

对于其他情况,它可以是带注释的错误处理程序

@ControllerAdvice(annotations = Controller.class)

答案 1 :(得分:2)

这是spring mvc中的全局异常处理程序。每次在应用程序中找到异常时都会调用它。我认为你在web.xml的帮助下只能控制404异常。

@ControllerAdvice
public class GlobalExceptionController {

    @ExceptionHandler(Throwable.class)
    @ResponseBody
    public ModelAndView handleAllException(Throwable ex,
            HttpServletResponse response) {

        ex.printStackTrace();
        // Set Status
        response.setStatus(500);
        // Set View
        ModelAndView model = new ModelAndView("500");
        model.addObject("navlabel", "");
        model.addObject("userActivity", new ArrayList<String>());
        // Set exception Message
        model.addObject("errMsg", ex.getMessage());
        return model;
    }
}

答案 2 :(得分:0)

您可以创建内部静态类@RestControllerAdvice。 Noot需要为此创建分离的@RestController。

@ControllerAdvice
public class BaseController {
private static final Logger logger = 
LoggerFactory.getLogger(BaseController.class);

@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public String handleException(Exception error, Model model) {
    logger.error("Error was: " + error.getMessage(), error);
    model.addAttribute("message", error.getMessage());
    model.addAttribute("stackTrace", error.getStackTrace());
    model.addAttribute("exception", error);
    return "error"; //return view
}

@RestControllerAdvice
public static class RestBaseController {

    private static final Logger logger = LoggerFactory.getLogger(RestBaseController.class);

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public String handleException(Exception error) {
        logger.error("Error was: " + error.getMessage(), error);

        return "error"; //return "error"
    }
}
}

答案 3 :(得分:0)

您可以编写两个异常处理程序来处理normal和rest / ajax请求异常。以下是用于说明解决方案的示例代码。

@ControllerAdvice(annotations = RestController.class)
@Order(1)
class RestExceptionHandler {
    @ExceptionHandler(MyException.class)
    @ResponseBody
    ResponseEntity<ErrorResponse> exceptionHandler() {
        ....
    }   
}

@ControllerAdvice(annotations = Controller.class)
@Order(2)
class ExceptionHandler {
    @ExceptionHandler(Exception.class)
    public ModelAndView handleError500(HttpServletRequest request, HttpServletResponse response, Exception ex) {
        ModelAndView mav = new ModelAndView("error");
        mav.addObject("error", "500");
        return mav;
    }
}