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

밤호박님의 프로필 이미지

작성한 질문수

실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발

상품 등록

@Valid 유효성 체크 시 질문 있습니다!

해결된 질문

20.08.22 18:09 작성

·

497

3

강사님 안녕하세요! 상품 등록하는 부분에도 유효성 검사를 추가 해봤는데요. Neither BindingResult nor plain target object for bean name 오류가 나서 검색해보니 @ModelAttribute를 붙이면 된다고 해서 해결했습니다.

근데 회원등록 시에는 @ModelAttribute를 사용하지 않았어서 비교해봤더니, 모델객체에 담을 때 클래스명이랑 똑같이 설정하면 정상 동작하더라구요.

오류는 해결했는데 @ModelAttribute를 붙여야될 때도 있고 안 붙여도 될 때도 있고,,,  왜 이렇게 동작하는지 궁금합니다..ㅎㅎ

그리고 여기서 @ModelAttribute가 무슨 역할을 해주는지도 궁금합니다.

model.addAttribute("form", new BookForm());
@Valid BookForm form 
=> 오류남

model.addAttribute("form", new BookForm());
@ModelAttribute("form") @Valid BookForm form 
=> 정상 동작

model.addAttribute("form", new BookForm());
@ModelAttribute @Valid BookForm form 
=> 오류남

model.addAttribute("bookForm", new BookForm());
@Valid BookForm form 
=> 정상 동작

답변 4

4

김영한님의 프로필 이미지
김영한
지식공유자

2020. 08. 24. 21:49

안녕하세요. 밤호박님^^

보내주신 코드를 보았습니다.

@PostMapping("/items/new")
public String create(@Valid BookForm form, BindingResult result) {
if (result.hasErrors()) {
return "items/createItemForm";
}

@Valid를 통해서 바인딩 오류가 발생하면 BindingResult에 오류 정보가 담기겠지요.

그리고 if 문을 타서 items/createItemForm으로 이동하게 됩니다.

그런데 여기서 createItemForm.html을 열어보시면 form이라는 객체를 model에서 찾아서 사용하게 되어 있습니다.

<form th:action="@{/items/new}" th:object="${form}" method="post">

결국 해당 오류는 이 thymeleaf에서 발생한 오류입니다.

그러면 어떤케이스에 성공하고 실패할까요?

성공

1. @ModelAttribute("form") @Valid BookForm from이라고 파라미터를 받으면 성공하고

실패

2. @Valid BookForm from

3. @ModelAttribute @Valid BookForm from

사실 @ModelAttribute는 생략할 수 있습니다. 그래서 사실 1,2,3 모두 @ModelAttribute가 적용되었다고 보시면 됩니다.

그러면 어떤 차이가 있을까요? @ModelAttribute는 컨트롤러에서 파라미터로 http 데이터를 받는 역활도 하지만, 한가지 역할이 더있습니다. 바로 다음과 같이 model 객체에 @ModelAttribute를 자동으로 넣어주는 것이지요.

model.addAttribute("form"),  form)

그런데 여기서 이름이 있습니다. 이 이름을 생략하면 BeanName 규칙을 따른 이름을 적용합니다. 예를 들어서 BookForm이면 bookForm(첫글자만 소문자로 처리)이라는 이름으로 다음과 같이 들어갑니다.

model.addAttribute("bookForm", form")

위에서 설명했듯이 thymeleaf 화면에서는 form이라는 이름 데이터를 찾는데, 2,3번 실패 케이스들은 모두 bookForm이라는 이름이 들어가 있어서 찾지 못한 것이지요.

그래서 오류도 Neither BindingResult nor plain target object for bean name 'form' available as request attribute

이렇게 발생했습니다^^

도움이 되셨길 바래요.

1

밤호박님의 프로필 이미지
밤호박
질문자

2020. 08. 25. 14:35

아하! 자세히 설명해주셔서 아주 잘 이해 되었습니다!!

다음 스프링 MVC 강의도 기대하겠습니다 ㅎㅎ

감사합니다 :)

0

제트브레인님의 프로필 이미지

2020. 10. 01. 01:34

저도 비슷한 에러였습니다.

model.addAttribute("form", new BookForm()); 
여기서 그냥 form 으로 선언시 
This application has no explicit mapping for /error, so you are seeing this as a fallback. 

result 를 로그로 찍어보니

Field error in object 'bookForm' on field 'name': rejected value []; codes [NotEmpty.bookForm.name,NotEmpty.name,NotEmpty.java.lang.String,NotEmpty];
------ 

피셜인데. 
타임리프 가 form 앞의 명시적으로 접두어를 붙여주지 않으면 자동으로 붙지만 model.attribute 에서도 자동으로 붙여주는 접두어를 타이핑 하지 않으면 못찾나 봅니다... "내가 form 이 왠지 bookForm 인거같아서 붙여주긴 했다만... 진짜 form이 bookForm 일까? " 하는 측면으로 생각해보고 bookForm 붙여주니 잘되니깐 진도상 그냥 넘기긴 했습니다 검증이 필요할것같지만 맞는것같아요

0

김영한님의 프로필 이미지
김영한
지식공유자

2020. 08. 23. 23:34

안녕하세요. 밤호박님

짐작가는 바는 있으나 코드를 좀 더 살펴봐야 할 것 같아요.

오류나는 케이스로 전체 프로젝트를 압축해서 올려주세요.

감사합니다.