Spring启动REST服务异常处理?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (73)

正在尝试建立一个大规模的REST服务服务器。使用SpringBoot1.2.1Spring4.1.5和Java 8

提问于
用户回答回答于

使用SpringBoot 1.3.1.RELEASE

spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false

使用SpringBoot 1.2.7 RELEASE

DispatcherServlet替换代码:

@ComponentScan()
@EnableAutoConfiguration
public class MyApplication extends SpringBootServletInitializer {
    private static Logger LOG = LoggerFactory.getLogger(MyApplication.class);
    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(MyApplication.class, args);
        DispatcherServlet dispatcherServlet = (DispatcherServlet)ctx.getBean("dispatcherServlet");
        dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
    }

或者尝试下:

// NEW CODE ABOVE REPLACES THIS! (12/04/15)
@Configuration
public class MyAppConfig {
    @Bean  // Magic entry 
    public DispatcherServlet dispatcherServlet() {
        DispatcherServlet ds = new DispatcherServlet();
        ds.setThrowExceptionIfNoHandlerFound(true);
        return ds;
    }
}
@EnableWebMvc
@ControllerAdvice
public class ServiceExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(Throwable.class)
    @ResponseBody
    ResponseEntity<Object> handleControllerException(HttpServletRequest req, Throwable ex) {
        ErrorResponse errorResponse = new ErrorResponse(ex);
        if(ex instanceof ServiceException) {
            errorResponse.setDetails(((ServiceException)ex).getDetails());
        }
        if(ex instanceof ServiceHttpException) {
            return new ResponseEntity<Object>(errorResponse,((ServiceHttpException)ex).getStatus());
        } else {
            return new ResponseEntity<Object>(errorResponse,HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @Override
    protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
        Map<String,String> responseBody = new HashMap<>();
        responseBody.put("path",request.getContextPath());
        responseBody.put("message","The URL you have reached is not in service at this time (404).");
        return new ResponseEntity<Object>(responseBody,HttpStatus.NOT_FOUND);
    }
    ...
}

请记住,我认为“@EnableWebMvc”注释在这里很重要。没有它,这一切似乎都是行不通的。仅此而已-您的Spring引导应用程序现在将捕获上述处理程序类中的所有异常,包括404,您可以随意使用它们。

最后一点--似乎没有办法让它捕获抛出的错误。我有一个奇怪的想法,使用方面来捕获错误并将它们转化为上面的代码可以处理的异常,但我还没有时间去尝试实现它。希望这能帮上忙。

如有任何评论/更正/改进,将不胜感激。

用户回答回答于

@RestControllerAdvice是为异常处理提供的,它是@ControllerAdvice@ResponseBody...。您可以删除@ResponseBody@ExceptionHandler方法在使用此新注释时。

@RestControllerAdvice
public class GlobalControllerExceptionHandler {

    @ExceptionHandler(value = { Exception.class })
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ApiErrorResponse unknownException(Exception ex, WebRequest req) {
        return new ApiErrorResponse(...);
    }
}

用于处理404错误@EnableWebMvc注释和应用程序的以下内容

...

扫码关注云+社区