SpringBootでは、主に以下の2レイヤーで扱う
@ControllerAdvice)public class UserNotFoundException extends RuntimeException {
public UserNotFoundException(String message) {
super(message);
}
}
RuntimeException:これを継承すると、Springによるロールバックなどと相性が良い@Service
public class UserService {
private final UserRepository repository;
public UserService(UserRepository repository) {
this.repository = repository;
}
public User findUser(Long id) {
return repository.findById(id)
.orElseThrow(() -> new UserNotFoundException("ユーザーが見つかりません:" + id));
}
}
.orElseThrow():例外発生import org.springframework.web.bind.annotation.*;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(UserNotFoundException.class)
@ResponseBody
@ReponseStatus(code = HttpStatus.NOT_FOUND)
public String handleUserNotFound(UserNotFoundException ex) {
return ex.getMessage();
}
@ExceptionHandler(Exception.class)
@ResponseBody
@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
public String handleOtherExceptions(Exception ex) {
return "内部エラーが発生しました";
}
}
@ControllerAdvice:全Controllerの例外を横断的に処理@ExceptionHandler:特定の例外に反応@ResponseStatus:HTTPステータスを指定@ResponseBody:レスポンスをそのまま返すpublic class ErrorResponse {
private String message;
private int code;
public ErrorResponse(String message, int code) {
this.message = message;
this.code = code;
}
// getter / setter
}
@ExceptionHandler(UserNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
@ResponseBody
public ErrorResponse handleUserNotFound(UserNotFoundException ex) {
return new ErrorResponse(ex.getMessage(), 404);
}