종우의 삶 (전체 공개)

MSA Project - 트러블 슈팅 - 1. null로 들어오는 입력 데이터 본문

카테고리 없음

MSA Project - 트러블 슈팅 - 1. null로 들어오는 입력 데이터

jonggae 2024. 7. 19. 16:55

프로젝트 진행 과정에 발생한 트러블 슈팅을 정리해본다.

 

프로젝트 진행 중에 있던 내용으로, 최종 프로젝트 상태와 문제 발생 당시의 상태는 다를 수 있음.

 

증상 : 

회원 가입 로직을 진행할 때, 입력한 메일 주소로 인증 메일을 보낸다.

그리고 링크를 클릭하면 회원가입이 정상적으로 완료되는 형태이다. 링크를 클릭한 순간 DB에 정상적으로 회원의 데이터가 저장이 된다.

 

회원 가입시 필요한 데이터는 다음과 같이 입력한다.

{
    "customerName": "testname",
    "password": "1234",
    "email": "test@email.com",
    "address": "무명도 무명시 도로명주소",
    "addressDetail": "0000호"
}

 

링크를 클릭하면, 입력받은 데이터를 바탕으로 DB에 저장을 하게되는데, 

이때 Null로 들어오는 데이터가 존재했다. -> eg) Password 값 : null로 표시

 

원인 파악:

가입시 입력받은 데이터는 JSON 형태이다. 이 데이터를 코드 상의 다른 곳에서 사용하려면 '역직렬화'를 거쳐 DTO상태의 객체로 만들어야 한다. 하지만 초기에는 DTO를 많이 생성하지 않고 그저 CustomerDto 하나로 사용을 했었다.

때문에 보안 처리를 위해 Password 부분에

 

@JsonProperty(access = JsonProperty.Access.WRITE_ONLY) 어노테이션을 사용하게 되었는데,

public class CustomerDto {

    private Long id;
    private String customerName;

    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) //보안관련 직렬화,역직렬화
    private String password;
    private String email;
    private String address;
    private String addressDetail;

    public static CustomerDto from(Customer customer) {

        return CustomerDto.builder()
                .id(customer.getId())
                .customerName(customer.getCustomerName())
                .email(customer.getEmail())
                .address(customer.getAddress().getAddress())
                .addressDetail(customer.getAddress().getAddressDetail())
                .build();

    }

 

이 어노테이션을 사용하면 역직렬화에서 제외되어 직접적으로 알 수 없게 되는 것이었다.

 

해결 방안

하지만 DB저장은 Password의 값도 알아야하므로, 결과적으로는 DTO를 2개로 나누게 되었다.

 

public class CustomerRequestDto {
    private String customerName;
    private String password;
    private String email;
    private String address;
    private String addressDetail;

}
public class CustomerResponseDto {

    private String customerName;
    private String email;
    private String address;
    private String addressDetail;

    public static CustomerResponseDto from(Customer customer) {
        return CustomerResponseDto.builder()
                .customerName(customer.getCustomerName())
                .email(customer.getEmail())
                .address(customer.getAddress().getAddress())
                .addressDetail(customer.getAddress().getAddressDetail())
                .build();

    }

 

회원 가입시에는 CustomerRequestDto를 사용하여 필요한 데이터를 받아 저장을 하고, 

응답 데이터에는 CustomerResponseDto를 사용하여 민감 정보를 제외한 적절한 데이터만 표시하여 전송한다.

 

사실 이것말고도 여러 방법이 있었지만, DTO들을 분리하여 사용하는 것이 좀더 상황에 따라 변경하기도 쉽고 다른 메서드에 가져다 쓸 수도 있었다.

 

데이터를 받고, 내부에서 사용하는 방법을 이로써 좀 더 알게 되었다. DTO는 아주 다양한 기능을 할 수 있었다. 만들때는 귀찮고 헷갈릴 수 있지만, 꼭 필요한 곳에서는 사용하는것이 명확한 코드를 만드는데 도움이 될 것이다.

Comments