Welcome! Everything is fine.
Spring에서 @RequestBody를 사용할 때 주의해야 할 점 본문
삭제 기능 테스트 도중, 올바른 비밀번호를 입력해도 404 에러가 뜨는 문제가 있었다. 404 에러를 던지도록 설정한 부분은 DB에 있는 비밀번호와 입력한 비밀번호가 틀리는 경우 발생한다.
이것저것 시도해보다 Repository Layer에서 정확한 scheduleId와 password가 출력되는 것을 확인한 후, 비밀번호를 검증하는 Service Layer에서 다음과 같이 출력해봤다.
System.out.println("db password = " + current.getPassword());
System.out.println("input password = " + password);
System.out.println("equals = " + current.getPassword().equals(password));
그 결과는 다음과 같았다. JSON 형식의 문자열이 그대로 들어온 것이다.
Controller에서 보니 비밀번호를 String 그대로 넣은 것이 문제였다.
@DeleteMapping("/{scheduleId}")
public ResponseEntity deleteSchedule(
@PathVariable Long scheduleId,
@RequestBody(required = false) String password
) {
scheduleService.deleteSchedule(scheduleId, password);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
- inputPassword → {"password": "1111"} (JSON 객체)
- dbPassword → "1111" (String)
따라서 String 타입이 아닌 ScheduleRequestDto 타입으로 변경한 뒤 dto에서 getPassword()를 해서 비밀번호만 넘겨주었다.
@DeleteMapping("/{scheduleId}")
public ResponseEntity<Void> deleteSchedule(
@PathVariable Long scheduleId,
@RequestBody ScheduleRequestDto dto
) {
scheduleService.deleteSchedule(scheduleId, dto.getPassword());
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
변경 후 다시 로그를 출력해보니 원하던 결과가 나왔다.
또한 Postamn에서의 테스트도 성공하였다.
이 과정을 통해 @RequestBody에서 JSON 데이터를 받을 때 String 대신 DTO 객체를 사용하는 것이 좋다는 것을 알게 되었다.
여기서 또 수정된 부분이 있는데, required = false로 적은 부분을 삭제한 부분이다. @RequestBody(required = true) 가 설정되어 있으면, 클라이언트는 JSON을 반드시 보내야 하지만, 특정 필드는 null이 될 수도 있다. 이때, @RequestBody(required = false)로 변경하면 요청 본문이 없어도 예외가 발생하지 않는다. 비밀번호가 선택 사항이라면 false로 하는 것도 고려할 수 있지만 보통 비밀번호는 필수값이기 때문에 사용하지 않는다.
'TIL' 카테고리의 다른 글
왜 엔티티에 Setter를 사용하면 안 될까? (0) | 2025.02.13 |
---|---|
INSERT 됐지만 테이블이 안보이는 문제(@Transactional) (0) | 2025.02.12 |
queryForObject() vs query() (0) | 2025.02.03 |
[TIL] 네트워크, HTTP와 HTTP의 특징 (0) | 2025.01.22 |
[TIL] 계산기 과제 해설, 와일드카드, 타입 이레이저 (0) | 2025.01.10 |