[맛침반] 트러블 슈팅 - @ModelAttribute와 객체 안의 객체 검증하기

6720·2024년 3월 7일

프로젝트 맛침반

목록 보기
10/12

현재 상황

저번에 새로 발생하는 예외에 대해 처리해봤다. RestaurantRegisterRequest 안의 RestaurantCreateRequest, RestaurantImageCreateRequest, MenuCreateRequest 검증이 제대로 작동하는지 확인하기 위해 다음과 같이 일부러 값을 하나 틀려봤다.

RestaurantCreateRequest의 name에는 @NotEmpty가 걸려있기 때문에 원래대로라면 다시 검증 에러가 발생해야 한다.

하지만 다른 에러가 일어났다. 해당 에러는 검증 작업이 모두 끝난 다음에 발생하는 에러이기 때문에 검증 작업이 제대로 작동하지 않음을 확인했다.

사태 파악

@Setter  
@Getter  
@Schema(description = "매장 등록 Request")  
public class RestaurantRegisterRequest {  
  
    @Schema(description = "매장 정보")  
    @NotNull(message = "매장 정보를 등록해주세요.")  
    private RestaurantCreateRequest restaurant;  
  
    @Schema(description = "매장 이미지 정보")  
    @NotNull(message = "매장 이미지 정보를 등록해주세요.")  
    private List<RestaurantImageCreateRequest> images;  
  
    @Schema(description = "메뉴 정보")  
    @NotNull(message = "메뉴 정보를 등록해주세요.")  
    private List<MenuCreateRequest> menus;  
}

현재 RestaurantRegisterRequest는 다음처럼 세 객체를 가지고 있지만, 객체 내부까지 검증이 돌아가지 않는다. 현재 검증은 세 객체의 정보가 들어왔는지 정도만 확인하고 빠지고 있다.

문제 해결

@Valid

@Setter  
@Getter  
@Schema(description = "매장 등록 Request")  
public class RestaurantRegisterRequest {  
  
    @Schema(description = "매장 정보")
    @Valid
    @NotNull(message = "매장 정보를 등록해주세요.")  
    private RestaurantCreateRequest restaurant;  
  
    @Schema(description = "매장 이미지 정보")
    @Valid
    @NotNull(message = "매장 이미지 정보를 등록해주세요.")  
    private List<RestaurantImageCreateRequest> images;  
  
    @Schema(description = "메뉴 정보")
    @Valid
    @NotNull(message = "메뉴 정보를 등록해주세요.")  
    private List<MenuCreateRequest> menus;  
}

만약 객체 안의 객체를 검증하고 싶다면 @Valid를 사용하면 된다.

트러블 슈팅 속 트러블 슈팅

❗ 제대로 값이 전송되지 않음

(포스트맨맨님 한판해요)

다음처럼 menu와 image에 대한 정보는 넣지 않았고, @NotEmpty인 name을 제외했다.

하지만 결과에는 답을 제대로 작성한 부분에도 에러가 나타났다.

해결 - @ModelAttribute와 @Setter

컨트롤러 메서드의 파라미터로 DTO를 사용할 때, @ModelAttribute를 추가하게 되면, 객체가 폼 데이터로부터 바인딩되도록 할 수 있다.
컨트롤러 메서드의 파라미터로 DTO를 사용하게 되면, 해당 DTO에 대한 setter 메서드가 존재해야 한다.
나는 RestaurantRegisterRequest에는 @Setter를 작성했지만, 나머지 셋 객체에는 작성하지 않았기 때문에 인식하지 못한 것이다.
그래서 각 DTO에 @Setter를 추가하였다.

profile
뭐라도 하자

0개의 댓글