요구사항
- HTTP Protocol을 요청했을 때 DB에 일치하는 값이 없다면, 일치하는 데이터가 없다는 의미의
NoSuchDataException
을 만들어 예외 처리를 해준다.- User 테이블의 경우 username과 email이 unique로 설정되어 있으므로 POST 요청을 할 때 이미 존재하는 username이나 email이라면
DuplicateKeyException
을 처리하도록 한다.- 각 테이블의 Key 중 Not Null로 설정된 key 값이 null로 POST 되는 경우
DataIntegrityViolationException
을 처리하도록 한다.
파일 위치
코드
package <project name>.exception;
public class NoSuchDataException extends RuntimeException {
public NoSuchDataException(String message) {
super(message);
}
}
getUserList
: 테이블이 비어있으면 빈 리스트 반환
getUserById
: 일치하는 데이터가 없으면 null 반환
updateUser
: update된 데이터가 없으면 0 반환
deleteUser
: delete된 데이터가 없으면 0 반환
NoSuchDataException
을 throw 한다.api의 실행 결과를 dto에 code, message로 담아 보내기 위해 code의 의미를 설정해준다.
파일 위치
코드
package <project name>.consts;
public enum ResCode {
SUCCESS(0), NO_SUCH_DATA(-1), DUPLICATE_KEY(-2), NULL_VALUE(-3), UNKNOWN(-99);
// 성공했을 때, 일치하는 data가 없을 때, Not Null Key가 Null 값으로 왔을 때, 다른 exception이 발생했을 때
private final int value;
ResCode(int value) {
this.value = value;
}
public int value() {
return value;
}
}
UserController
의updateUser
메서드가 실행될 때 반환되는 클래스
package <project name>.dto.user;
import <project>.consts.ResCode;
import lombok.Data;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class UpdateUserRespDto { // default로 성공했을 때의 값을 넣어둔다.
private int code = ResCode.SUCCESS.value();
private String message;
}
@JsonInclude(JsonInclude.Include.NON_NULL)
- 데이터를 전송할 때 Null 값이 아닌 데이터들만 전송하는 annotation.
- 성공했을 때의 message는 default로 null로 설정되어 있으므로 데이터의 크기를 줄이기 위해 의미 없는 데이터는 보내지 않는다.
코드
상황에 따라 updateUserRespDto
의 code와 message를 다르게 설정해준다.
Exception이 발생하면 console에 ERROR
log가 찍히도록 log.error()
를 작성한다. (@Slf4j
lombok 사용)
@Slf4j lombok을 사용하지 않으면 "private static final Logger log = LoggerFactory.getLogger(AlbumController.class);" 코드를 작성해줘야 한다.
에러 발생시
WARN
log만 나타난다.@PutMapping("/users/{id}")
public UpdateUserRespDto updateUser(@PathVariable Long id, @RequestBody UpdateUserReqDto updateUserReqDto) {
UpdateUserRespDto updateUserRespDto = new UpdateUserRespDto();
try {
UserVo userVo = new UserVo(id, updateUserReqDto.getName(), updateUserReqDto.getUsername(), updateUserReqDto.getEmail(), updateUserReqDto.getPassword(), updateUserReqDto.getAddress(), updateUserReqDto.getPhone(), updateUserReqDto.getWebsite(), updateUserReqDto.getCompany());
userService.updateUser(userVo);
} catch (NoSuchDataException e) {
updateUserRespDto.setCode(ResCode.NO_SUCH_DATA.value());
updateUserRespDto.setMessage("No such user exists.");
} catch (Exception e) {
log.error("[UserController updateUser]", e);
updateUserRespDto.setCode(ResCode.UNKNOWN.value());
updateUserRespDto.setMessage(e.getLocalizedMessage());
}
return updateUserRespDto;
}
try
: 프로그램이 정상적으로 실행됐을 때의 실행 코드
catch
: 예외가 발생했을 때의 실행 코드
DuplicateKeyException
과 DataIntegrityViolationException
이 발생하면 createUserRespDto
에 code와 message를 담아준다.@PostMapping("/users")
public CreateUserRespDto createUser(@RequestBody CreateUserReqDto createUserReqDto) {
CreateUserRespDto createUserRespDto = new CreateUserRespDto();
try {
UserVo userVo = new UserVo(0L, createUserReqDto.getName(), createUserReqDto.getUsername(), createUserReqDto.getEmail(), createUserReqDto.getPassword(), createUserReqDto.getAddress(), createUserReqDto.getPhone(), createUserReqDto.getWebsite(), createUserReqDto.getCompany());
userService.createUser(userVo);
} catch (DuplicateKeyException e) {
createUserRespDto.setCode(ResCode.DUPLICATE_KEY.value());
createUserRespDto.setMessage("Duplicate 'username' or 'email'.");
} catch (DataIntegrityViolationException e) {
createUserRespDto.setCode(ResCode.NULL_VALUE.value());
createUserRespDto.setMessage("'username', 'email' are required.");
} catch (Exception e) {
log.error("[UserController createUser]", e);
createUserRespDto.setCode(ResCode.UNKNOWN.value());
createUserRespDto.setMessage(e.getLocalizedMessage());
}
return createUserRespDto;
}
존재하지 않는 id의 데이터를 요청했을 때 NoSuchDataException
이 처리된 모습
이미 존재하는 username이나 email을 전송했을 때 DuplicateKeyException
이 처리된 모습
DataIntegrityViolationException
이 처리된 모습Source Code
https://github.com/wooryung/REST_API_Basic.git