본문 바로가기
🔓 영구 노트

Completed 406 NOT_ACCEPTABLE

by 파랭이가 룰루랄라 2022. 5. 27.

프로젝트를 진행하며 delete 메서드를 처리할 때에 response로 HttpStatus.OK만을 반환하였는데 이를 프론트에서 mapping 하는데 불편하다는 의견이 있어서 DefaultDeleteResponseDto라는 클래스를 만들어서 message를 넘겨주었습니다.

 

코드를 작성한 후에 실제로 동작하는지 확인하기 위해 프로젝트를 실행시켜보니 406 NOT_ACCEPTABLE이 발생하였고, 많은 이유들이 있겠지만 객체를 json으로 변환하지 못해서 발생하는 오류가 가장 유력했습니다.

public class DefaultDeleteResponseDto {
    private String message;

    @Builder
    public DefaultDeleteResponseDto(String message) {
        this.message = message;
    }
}

위와 같이 getter가 없으면 ObejctMapper에서 writeValueAsString과 같은 함수를 실행시킬 수 없습니다. 따라서 위의 문제를 해결하기 위해서는 2가지 방법 중에 하나를 선택할 수 있습니다.

  • 클래스에 @JsonAutoDetect를 붙여주고 json 객체로 변환시킬 변수들 마다 @JsonProperty를 붙여주는 것
  • 클래스의 변수들에 Getter 함수들을 만들어주는 것

첫 번째 해결방법을 사용하면 코드는 다음과 같습니다.

@JsonAutoDetect
public class DefaultDeleteResponseDto {
    @JsonProperty
    private String message;

    @Builder
    public DefaultDeleteResponseDto(String message) {
        this.message = message;
    }
}

두 번째 해결방법을 사용하면 코드는 다음과 같습니다.

@Getter
public class DefaultDeleteResponseDto {
    private String message;

    @Builder
    public DefaultDeleteResponseDto(String message) {
        this.message = message;
    }
}

첫 번째 방법을 사용하면 사용할 것과 사용하지 않을 것을 명시적으로 구분하는 것에는 장점이 있을 것 같지만 dto를 만든다는 것은 필요한 데이터만 적재적소에 사용하겠다는 것을 코드로 명시하는 것입니다.

 

따라서 dto에 있는 변수들은 모두 response 또는 request에 사용되므로 getter를 만드는 것이 코드의 의미를 파악하는데 더 이점이 있을 것 같습니다.

 

다음은 DefaultDeleteResponseDto를 응답으로 보내는 컨트롤러 코드입니다.

@DeleteMapping("/question/{id}")
public ResponseEntity<DefaultDeleteResponseDto> deleteByIdV1(
        @PathVariable Long id) {
    questionService.findByIdOrThrow(id);
    questionService.deleteById(id);
    return ResponseEntity.ok(
            new DefaultDeleteResponseDto("질문이 성공적으로 삭제되었습니다"));
}

ResponseEntity의 body를 dto로 설정해주게 되면 HttpEntity의 body 값이 DefaultDeleteResponseDto로 설정이 됩니다. 후에 sevlet 필터를 통과하면 객체가 json 응답으로 변환되어 응답이 성공적으로 반환되게 됩니다.

Postman 테스트 결과

해당 오류를 공부하며 ResponseEntity의 상속 구조, jackson 라이브러리를 통해 객체가 json이 되고, json이 객체가 되는 부분들도 추가적으로 알게 되었습니다.

댓글