spring boot覆盖默认的REST异常处理程序

时间:2016-02-22 21:12:59

标签: spring rest groovy spring-boot

我无法在REST api中覆盖默认的spring boot错误响应。我有以下代码

@ControllerAdvice
@Controller
class ExceptionHandlerCtrl {

    @ResponseStatus(value=HttpStatus.UNPROCESSABLE_ENTITY, reason="Invalid data")
    @ExceptionHandler(BusinessValidationException.class)
    @ResponseBody
    public ResponseEntity<BusinessValidationErrorVO> handleBusinessValidationException(BusinessValidationException exception){
        BusinessValidationErrorVO vo = new BusinessValidationErrorVO()
        vo.errors = exception.validationException
        vo.msg = exception.message
        def result =  new ResponseEntity<>(vo, HttpStatus.UNPROCESSABLE_ENTITY);
        result

    }

然后在我的REST api中,我抛出了这个BusinessValidationException。调用此处理程序(我可以在调试器中看到它)但是我仍然有默认的spring boot REST错误消息。有没有办法覆盖并使用默认值作为后备?带有常规的Spring Boot版本1.3.2。最诚挚的问候

2 个答案:

答案 0 :(得分:8)

从您的方法中删除@ResponseStatus。它会产生不良副作用而您不需要它,因为您在HttpStatus.UNPROCESSABLE_ENTITY中设置了ResponseEntity

来自JavaDoc on ResponseStatus

  

警告:在异常类上使用此批注时,或者在设置此批注的reason属性时,将使用HttpServletResponse.sendError方法。

     

使用HttpServletResponse.sendError,响应被视为已完成,不应再写入。此外, Servlet容器通常会编写HTML错误页面,因此使用了不适合REST API的原因。对于此类情况,最好使用ResponseEntity作为返回类型,并避免完全使用@ResponseStatus

答案 1 :(得分:0)

我建议你阅读这个问题:Spring Boot REST service exception handling

在那里你可以找到一些例子来解释如何组合ErrorController / ControllerAdvice以捕获任何异常。

特别检查这个答案:

https://stackoverflow.com/a/28903217/379906

您应该从方法handleBusinessValidationException中删除注释 @ResponseStatus

另一种必须重写默认错误消息的方法是使用带注释@RequestMapping的控制器(&#34; / error&#34;)。控制器必须实现 ErrorController 接口。

这是我在我的应用中使用的错误控制器。

@RestController
@RequestMapping("/error")
public class RestErrorController implements ErrorController
{
    private final ErrorAttributes errorAttributes;

    @Autowired
    public MatemoErrorController(ErrorAttributes errorAttributes) {
        Assert.notNull(errorAttributes, "ErrorAttributes must not be  null");
    this.errorAttributes = errorAttributes;
  }

@Override
public String getErrorPath() {
    return "/error";
}

@RequestMapping
public Map<String, Object> error(HttpServletRequest aRequest) {

    return getErrorAttributes(aRequest, getTraceParameter(aRequest));
}

private boolean getTraceParameter(HttpServletRequest request) {
    String parameter = request.getParameter("trace");
    if (parameter == null) {
        return false;
    }
    return !"false".equals(parameter.toLowerCase());
}

private Map<String, Object> getErrorAttributes(HttpServletRequest  aRequest, boolean includeStackTrace)
{
    RequestAttributes requestAttributes = new  ServletRequestAttributes(aRequest);
    return errorAttributes.getErrorAttributes(requestAttributes,  includeStackTrace);
}  }