[Project] Stackoverflow 클론코딩하기 - 댓글 CRUD 기능 구현 (Front-end와 통신하며 발생한 문제 해결)

정동아·2023년 8월 22일
0

Stackoverflow

목록 보기
7/8

지난 게시글처럼 구현을 했는데, 프론트와 작업을하며 두가지 문제가 생겼다.

  • 서버 응답이 json으로 안와서 클라에서 syntaxerror: unexpected end of json input 에러가 생겼다.
  • ResponseBody 에 null값이 전달된다. (memberId, nickname,questionId 값이 null로 전달되었다. db에는 제대로 들어갔다..)

위 두가지 문제를 해결한 방법을 정리하려한다.

1. syntaxerror: unexpected end of json input 에러

위 에러는 찾아보니까 JSON을 파싱 하려 시도했지만, 해당 문자열이 JSON 형식에 맞지 않을 때 발생한다고한다.
생각해보니 CommentCoontroller에서 return 값으로 JSON형식의 문자열을 보내주고 있지 않고 있다는게 기억나서 부랴부랴 controller를 수정했다.

CommentController

//질문에 대한 답변을 등록
    @PostMapping
    public ResponseEntity postComment(@Valid @RequestBody CommentDto.Post post,
                                      @PathVariable("question-id") @Positive long questionId){

        //commentPostDto.setQuestionId(questionId);
        Comment postComment = mapper.commentPostDtoToComment(post);
        Comment response = commentService.createComment(postComment);

        return new ResponseEntity<>(mapper.commentToCommentResponseToDto(response), HttpStatus.CREATED);
    }
  • ResponseBody에 엔티티를 다시 dto로 변환한 값과 HTTP 상태를 전달해줘서 해결했다. (dto로 변환한 값만 줘도됨)

근데 이렇게 ResponseBody를 프론트에 전달하니까, 다른 에러가 나왔다!

2. ResponseBody 에 null값이 전달되는 문제

다른 에러는 ResponseBody 에 null값이 들어가서 500 에러가 떴다.
필요한 데이터는 다 작성해서 넣었는데 왜 null로 나올까!!

mapstruct를 사용해서 매핑을 해줬는데, CommentMapperImpl를 확인해보니

  public CommentResponseDto commentToCommentResponseToDto(Comment comment) {
        if (comment == null) {
            return null;
        } else {
            CommentResponseDto commentResponseDto = new CommentResponseDto();
            commentResponseDto.setCommentId(comment.getCommentId());
            commentResponseDto.setNickname(comment.getNickname());
            commentResponseDto.setCommentBody(comment.getCommentBody());
            commentResponseDto.setCreatedAt(comment.getCreatedAt());
            return commentResponseDto;
        }
    }

comment를 다시 dto로 변환해줄 때 questinId, memberId에 대한 매핑 부분이 빠져있었다..
commentPostDtoToCommen만 특정 필드 questinId, memberId를 어떻게 매핑할 지 지정해주고 commentToCommentResponseToDto는 안해줬던 것이다..

그래서

  @Mapping(source = "question.questionId", target = "questionId")
    @Mapping(source = "member.memberId", target = "memberId")
    @Mapping(source = "member.nickname", target = "nickname")
    CommentResponseDto commentToCommentResponseToDto (Comment comment);

이번엔 닉네임까지 같이 지정해줬다. (commentPostDtoToComment에도 닉네임 지정 애너테이션 추가해줌 )

이렇게 해주면 값 제대로 들어간다!
dto -> entity는 특정해줘서 db에 값이 제대로 맞춰 들어갔는데, entity -> dto는 특정해주지 않아서 responseBody에 null로 들어간거같다.

왕복으로 처리 안하고 편도만 처리한 나의 멍청함에 박수를 보낸다 ..ㅎㅎㅎ


사실 프론트분들이 에러 해결해달라고할 땐 정해진 빌드 시간이 지나기도 했고 마음이 조급해져서 매핑이 안되길래 손으로 매핑해버렸다 ㅋㅋ,,

 default CommentResponseDto commentToCommentResponseToDto(Comment comment){
        CommentResponseDto commentResponseDto = new CommentResponseDto();
        commentResponseDto.setCommentId(comment.getCommentId());
        commentResponseDto.setNickname(comment.getMember().getNickname());
        commentResponseDto.setMemberId(comment.getMember().getMemberId());
        commentResponseDto.setQuestionId(comment.getQuestion().getQuestionId());
        commentResponseDto.setCommentBody(comment.getCommentBody());
        commentResponseDto.setCreatedAt(comment.getCreatedAt());
        return commentResponseDto;
    }

이렇게.. ㅋㅋㅋ...
블로그에 정리하려하다 왜 특정할 생각을 안했지? 하며 코드 수정했고, 정상적으로 작동해서 처음부터 저렇게 작성한척 올렸다 😝

2개의 댓글

comment-user-thumbnail
2023년 8월 23일

기억까지 조작하는게 찐 개발자같아지네....후후....

1개의 답글