前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >猫头鹰的深夜翻译:Spring REST服务异常处理

猫头鹰的深夜翻译:Spring REST服务异常处理

作者头像
眯眯眼的猫头鹰
发布2019-03-13 16:36:44
7400
发布2019-03-13 16:36:44
举报

前言

这篇教程主要专注于如何优雅的处理WEB中的异常。虽然我们可以手动的设置ResponseStatus ,但是还有更加优雅的方式将这部分逻辑隔离开来。Spring提供了整个应用层面的异常处理的抽象,并且只是要求您添加一些注释 - 它会处理其他所有内容。下面是一些代码的示例

如何手动处理异常

下面的代码中, DogController将返回一个ResponseEntity实例,该实例中包含返回的数据和HttpStatus属性

  • 如果没有抛出任何异常,则下面的代码将会返回List<Dog>数据作为响应体,以及200作为状态码
  • 对于DogsNotFoundException,它返回空的响应体和404状态码
  • 对于DogServiceException, 它返回500状态码和空的响应体
代码语言:javascript
复制
@RestController
@RequestMapping("/dogs")
public class DogsController {
    @Autowired private final DogsService service;
    @GetMapping
    public ResponseEntity<List<Dog>> getDogs() {
        List<Dog> dogs;
        try {
            dogs = service.getDogs();
        } catch (DogsServiceException ex) {
            return new ResponseEntity<>(null, null, HttpStatus.INTERNAL_SERVER_ERROR);
        } catch (DogsNotFoundException ex) {
            return new ResponseEntity<>(null, null, HttpStatus.NOT_FOUND);
        }
        return new ResponseEntity<>(dogs, HttpStatus.OK);
    }
}

这种处理异常的方式最大的问题就在于代码的重复。catch部分的代码在很多其它地方也会使用到(比如删除,更新等操作)

Controller Advice

Spring提供了一种更好的解决方法,也就是Controller Advice。它将处理异常的代码在应用层面上集中管理。

现在我们的的DogsController的代码更加简单清晰了:

代码语言:javascript
复制
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
import static org.springframework.http.HttpStatus.NOT_FOUND;

@ControllerAdvice
public class DogsServiceErrorAdvice {
    @ExceptionHandler({RuntimeException.class})
    public ResponseEntity<String> handleRunTimeException(RuntimeException e) {
        return error(INTERNAL_SERVER_ERROR, e);
    }
    @ExceptionHandler({DogsNotFoundException.class})
    public ResponseEntity<String> handleNotFoundException(DogsNotFoundException e) {
        return error(NOT_FOUND, e);
    }
    @ExceptionHandler({DogsServiceException.class})
    public ResponseEntity<String> handleDogsServiceException(DogsServiceException e){
        return error(INTERNAL_SERVER_ERROR, e);
    }
    private ResponseEntity<String> error(HttpStatus status, Exception e) {
        log.error("Exception : ", e);
        return ResponseEntity.status(status).body(e.getMessage());
    }
}
  • handleRunTimeException:这个方法会处理所有的RuntimeException并返回INTERNAL_SERVER_ERROR状态码
  • handleNotFoundException: 这个方法会处理DogsNotFoundException并返回NOT_FOUND状态码。
  • handleDogsServiceException: 这个方法会处理DogServiceException并返回INTERNAL_SERVER_ERROR状态码

这种实现的关键就在于在代码中捕获需检查异常并将其作为RuntimeException抛出。

还可以用@ResponseStatus将异常映射成状态码

代码语言:javascript
复制
@ControllerAdvice
public class DogsServiceErrorAdvice {
    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ExceptionHandler({DogsNotFoundException.class})
    public void handle(DogsNotFoundException e) {}
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler({DogsServiceException.class, SQLException.class, NullPointerException.class})
    public void handle() {}
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler({DogsServiceValidationException.class})
    public void handle(DogsServiceValidationException e) {}
}

在自定义的异常上添加状态码

代码语言:javascript
复制
@ResponseStatus(HttpStatus.NOT_FOUND)
public class DogsNotFoundException extends RuntimeException {
    public DogsNotFoundException(String message) {
        super(message);
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-01-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 如何手动处理异常
  • Controller Advice
  • 在自定义的异常上添加状态码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档