Spring Boot中的REST异常映射

时间:2014-07-16 19:43:00

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

我正在开发一个具有自动配置和使用执行器的Spring Boot REST服务。当涉及异常层次时,spring(boot)如何处理异常处理?当一个例外扩展另一个例外时,@ExceptionHandler可以用来发送一个不同的响应吗?

我有一个像这样定义的应用程序异常(我的异常扩展了RunTimeException,当然它扩展了Exception)。

public class ResourceNotFoundException extends RuntimeException {
    public ResourceNotFoundException() {
        super();
    }

    public ResourceNotFoundException(String message, Throwable cause) {
        super(message, cause);
    }

    public ResourceNotFoundException(String message) {
        super(message);
    }

    public ResourceNotFoundException(Throwable cause) {
        super(cause);
    }

}

我的REST服务控制器定义如下:

@RestController
@RequestMapping(value = "/sample")
public class SampleController extends AbstractRestHandler {
      @RequestMapping(value="/test",
                method = RequestMethod.GET,
                produces = {"application/xml", "application/json"})
      @ResponseStatus(HttpStatus.OK)
      public @ResponseBody SampleTest getSampleTest(HttpServletRequest request, HttpServletResponse response) {
      // for demo only -- to test exception handling
      SampleTest s = null;
      if (null==s) throw new ResourceNotFoundException();
      return s;
}

控制器超类AbstractRestHandler定义了异常处理行为。当我的应用程序抛出(更具体的)ResourceNotFoundException时,我希望用NOT_FOUND进行响应,我想用INTERNAL_SERVER_ERROR响应任何其他异常。 (并且如上所示,ResourceNotFoundException间接地扩展了Exception)。问题是,即使抛出ResourceNotFoundException,应用程序也总是返回INTERNAL_SERVER_ERROR(使用我的自定义“我搞砸了”主体)。

public abstract class AbstractRestHandler {

    protected Logger log = LoggerFactory.getLogger(this.getClass());
    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ExceptionHandler(ResourceNotFoundException.class)
    public
    @ResponseBody
    RestErrorInfo handleResourceNotFoundException(ResourceNotFoundException ex, WebRequest request, HttpServletResponse response) {
        log.info("Converting Resource Not Found exception to RestResponse : " + ex.getMessage());

        return new RestErrorInfo(ex, "Sorry I couldn't find it :-(");
    }

    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(Exception.class)
    public
    @ResponseBody
    RestErrorInfo handleGeneralException(Exception ex, WebRequest request, HttpServletResponse response) {
        log.info("Converting Internal exception to RestResponse : " + ex.getMessage());

        return new RestErrorInfo(ex, "I messed up.");
    }
}

为了完整起见,这里是RestErrorInfo

的实现
public class RestErrorInfo {
    public final String detail;
    public final String message;

    public RestErrorInfo(Exception ex, String detail) {
        this.message = ex.getLocalizedMessage();
        this.detail = detail;
    }
}

非常感谢任何有关正确使用模式的帮助。

0 个答案:

没有答案