调用API时如何避开null检查?

时间:2019-01-14 17:22:31

标签: java spring spring-restcontroller

当我在Spring中编写RestController时,我总是检查object是否为null。我该如何逃避这张支票?

在下面的示例中,存在null检查,之后返回notFound或Http status404。因此,我不想一直检查它。

  @GetMapping(path = "/api/member/{member-id}")
  public ResponseEntity<Member> getMemberById(@PathVariable(name="member-id", required=true) final Long memberId) {
    final Member member = memberService.findById(memberId);
    if (member != null) {
      return ResponseEntity.ok(member);
    }
    return ResponseEntity.notFound().build();
  }

2 个答案:

答案 0 :(得分:2)

尽管您无法避免进行空检查,但可以将其从Controller移出服务(也可以使用Optional)。如果您正在寻找一种处理负面响应方案的通用策略,建议您使用Spring的RestControllerAdvice批注,该批注将为所有API启用全局异常处理:

我们首先将检查移至服务并在未找到记录的情况下引发自定义异常MemberNotFoundException

DefaultMemberService.java

public Member findById(final String memberId) {
  Optional<Member> member = memberRepository.findById(memberId);
  return member.orElseThrow(() -> new MemberNotFoundException("Invalid member Id"));
}

在Controller中,只需调用service方法,然后返回响应即可。

MemberController.java

@GetMapping(path = "/api/member/{member-id}")
public ResponseEntity<Member> getMemberById(@PathVariable(name="member-id", required=true) final Long memberId) {

  return ResponseEntity.ok().body(memberService.findById(memberId));
}

如您所见,我们没有明确处理异常。相反,我们通过将异常类映射到响应(错误消息,响应代码)来让RestControllerAdvice为我们做这件事:

ExceptionHandlerControllerAdvice.java

@RestControllerAdvice
public final class ExceptionHandlerControllerAdvice {

  @ExceptionHandler({ MemberNotFoundException.class })
  @ResponseStatus(HttpStatus.NOT_FOUND)
  ResponseEntity<ErrorDto> handleRecordNotFound(MemberNotFoundException ex) {
    return ResponseEntity.status(HttpStatus.NOT_FOUND)
        .body(new ErrorDto(ex.getMessage));
  }
}

其中ErrorDto(简体)为:

public class ErrorDto {
  private String message;

  public ErrorDto(String msg) { this.message = msg; }

  public String getMessage() { return this.message; }
}

参考:RestControllerAdviceExceptionHandler

答案 1 :(得分:1)

那很好。

或者,memberService.findById可以返回Optional<Member>,然后您可以执行以下操作:

memberService.findById(memberId)
  .map(it -> ResponseEntity.ok(member).build())
  .orElse(ResponseEntity.notFound().build());

您还可以将返回类型“编码”为异常类型,并且每当您在数据库层/层上搜索请求的资源时,如果不存在,则可以抛出将该异常转换为{{1} }下游–在某些异常处理程序中。在那种情况下,您无需担心控制器中不同的返回类型,但是所有这些魔术也都具有一些缺点,例如,对于新来者来说,仅通过检查代码,除非您已经花了一段时间了。

此外,如果您不希望重复相同的HTTP Not Found检查,则可以将其包装在通用/通用方法中。