Notice
Recent Posts
Recent Comments
Link
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Tags
more
Archives
Today
Total
관리 메뉴

히콩쓰 개발 일지

@ReqestBody String 사용 시 Json이 그대로 입력되는 이유 본문

Spring

@ReqestBody String 사용 시 Json이 그대로 입력되는 이유

용히콩 2023. 11. 14. 20:27

게시판 CRUD를 개발하던 중, 아래와 같은 요구사항을 구현하다 문제에 직면했다.

선택한 게시글 삭제 기능

  • 선택한 게시글을 삭제할 수 있습니다.
  • 서버에 게시글 삭제를 요청할 때 비밀번호를 함께 전달합니다.
  • 선택한 게시글의 비밀번호와 요청할 때 함께 보낸 비밀번호가 일치할 경우에만 삭제가 가능합니다.

password를 매개변수로 전달해주고 이를 비교하는 로직을 작성하면 된다고 생각해 아래와 같이 Controller를 구현했다.


  
@DeleteMapping("/board/{id}")
public void removeBoard(@PathVariable Long id, @RequestBody String password){
boardService.removeBoard(id, password);
}

Postman에서 body에 json 형식으로 password를 전달했고,


  
http://localhost:8080/board/6
{
"password" : "1234"
}

비밀번호가 일치함에도, 일치하지 않는다는 오류를 출력해 디버깅으로 돌려봤다. (⭐은 중단점을 의미함)


  
public void removeBoard(Long id, String password) {
Board findBoard = boardRepository.findById(id);
if (findBoard.getPassword().equals(password)) {
boardRepository.deleteById(id);
} else {
System.out.println("비밀번호가 일치하지 않습니다.");
}
}

디버깅 결과,

password 가 기대값인 1234 로 입력되지 않고 json 형식 그대로 입력된 것을 확인할 수 있다.
이렇게 되면, DB에 저장된 값과 ✖️ 당연히 일치하지 않을 것이다 ✖️


@RequestBody의 역할은 HTTP의 Header와 Body 중에 Body로 들어온 데이터를 @RequestBody가 달린 Parameter에 넣어주는 역할이다.

이 때, Parameter가 String이면 그대로 넣어주지만,
Class라면 Jackson을 이용해 직렬화해서 매핑해준다.

이 경우는 String을 사용해 Jackson이 json을 직렬화 하지 않아 발생한 문제이다.


이 문제를 해결하기 위해, passwordDTO로 변경하는 방법을 고안했다.

  • password를 매개변수로 전달하는 것이 좋은 방법이 아니다.
    같은 맥락으로 url에 password가 노출되어서도 안 된다.

BoardDeleteRequestDto


  
import lombok.Getter;
@Getter
public class BoardDeleteRequestDto {
private Long id;
private String password;
}

Controller


  
@DeleteMapping("/board")
public void removeBoard(@RequestBody BoardDeleteRequestDto boardDeleteRequestDto){
boardService.removeBoard(boardDeleteRequestDto);
}

BoardService


  
public void removeBoard(BoardDeleteRequestDto boardDeleteRequestDto) {
Board findBoard = boardRepository.findById(boardDeleteRequestDto.getId());
if (findBoard.getPassword().equals(boardDeleteRequestDto.getPassword())) {
boardRepository.deleteById(boardDeleteRequestDto.getId());
} else {
System.out.println("비밀번호가 일치하지 않습니다.");
}
}

위와 같이 코드를 수정했다.

그 결과,

DTO로 전달된 password와 기존에 DB에 저장된 password의 값이 일치하는 것을 확인할 수 있다.
DB에서도 잘 삭제 되었다❗

해결 끝 ! 😚