인프런 커뮤니티 질문&답변

taehee-kim-dev님의 프로필 이미지
taehee-kim-dev

작성한 질문수

스프링 웹 MVC

@RequestBody와 @ModelAttribute

작성

·

359

0

안녕하세요, 수업 잘 보고 있습니다.

저는 Controller에서 RequestMapping을 할 때 습관적으로 @ModelAttribute를 적어주는데요,

Client단에서 JSON으로 요청을 보냈을 때,

@RequestBody와 함께 @ModelAttribute를 적으면 제대로 바인딩이 안되는 경험을 했습니다.

@RequiredArgsConstructor
@RestController
public class NotificationController {

    private final NotificationService notificationService;
    private final NotificationDeleteRequestDtoValidator notificationDeleteRequestDtoValidator;

    @InitBinder("notificationDeleteRequestDto")
    public void initBinderForNotificationDeleteRequestDtoValidator(WebDataBinder webDataBinder){
        webDataBinder.addValidators(notificationDeleteRequestDtoValidator);
    }

    @PostMapping(NOTIFICATION_DELETE_URL)
    public ResponseEntity deleteNotification(@SessionAccount Account sessionAccount,
                                             @Valid @RequestBody @ModelAttribute NotificationDeleteRequestDto notificationDeleteRequestDto,
                                             Errors errors){
        if(errors.hasErrors()){
            return ResponseEntity.badRequest().build();
        }
        // notificationService.deleteNotification(sessionAccount, notificationDeleteRequestDto);
        return ResponseEntity.ok().build();
    }
}

이렇게 하면 바인딩이 안되어 null값으로 들어오고,

@RequiredArgsConstructor
@RestController
public class NotificationController {

    private final NotificationService notificationService;
    private final NotificationDeleteRequestDtoValidator notificationDeleteRequestDtoValidator;

    @InitBinder("notificationDeleteRequestDto")
    public void initBinderForNotificationDeleteRequestDtoValidator(WebDataBinder webDataBinder){
        webDataBinder.addValidators(notificationDeleteRequestDtoValidator);
    }

    @PostMapping(NOTIFICATION_DELETE_URL)
    public ResponseEntity deleteNotification(@SessionAccount Account sessionAccount,
                                             @Valid @RequestBody NotificationDeleteRequestDto notificationDeleteRequestDto,
                                             Errors errors){
        if(errors.hasErrors()){
            return ResponseEntity.badRequest().build();
        }
        // notificationService.deleteNotification(sessionAccount, notificationDeleteRequestDto);
        return ResponseEntity.ok().build();
    }
}

이렇게 하면 바인딩이 잘 되더군요..

@ModelAttribute는 @RequestBody와 같이 쓰면 안되는건가요 원래?

아니면 제가 뭔가 잘못한 게 있는건가요?

답변 4

0

아 아니네요..

@PathVariable은 주소에 URI로 들어오지만

@RequestParam은 POST요청의 경우 본문에 들어오니까..

결국 @ModelAttribute는 요청 매개변수형태(key=value)는 쿼리파라미터든 본문이든 모두 매핑이 되지만, JSON형태는 매핑이 안되는 거군요? 

0

백기선님의 프로필 이미지
백기선
지식공유자

대충 맞습니다만 조금 더 구체적으로요. @MA, @PV, @RP로 받는 값들은 그럼 요청 본문에 들어오는 내용이 아닌가요? 어디로 들어오나요?

0

@ModelAtteibute는 @PathVariable이나 @RequestParam으로 들어오는 값들만 매핑이 돼서,

@RequestBody로 들어오는, 즉 JSON형태로 요청 body 본문에 들어오는 내용은 매핑을 못하는 것 같은데.. 맞나요??

0

백기선님의 프로필 이미지
백기선
지식공유자

수업 중에 @MA와 @RB를 다루는 수업이 있으니 공부를 하신다음에 천천히 생각해 보시고 스스로 생각하는 답을 적어주시면 리뷰해 드리겠습니다.

taehee-kim-dev님의 프로필 이미지
taehee-kim-dev

작성한 질문수

질문하기