inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

스프링 MVC 2편 - 백엔드 웹 개발 활용 기술

BindingResult2

V1, V2차이 그리고 @ModelAttribute 기능에 대해서 질문이에용 ㅠㅠ

733

g g

작성한 질문수 29

4

V1, V2 에서 값을 잘못 입력했을때 addForm으로 넘어가잖아요 V1은 잘못 입력한 데이터가 유지되는데 V2는 왜 유지가 되지 않나요?

V1

@PostMapping("/add")
public String addItem(@ModelAttribute Item item, RedirectAttributes redirectAttributes, Model model) {
    //검증에 실패하면 다시 입력 폼으로
    if (!errors.isEmpty()) {
        log.info("errors = {} ", errors);
        model.addAttribute("errors", errors);
        //model.addAttribute("item", item) <<자동추가되는거아님?
        return "validation/v1/addForm";
    }

V2

public String addItemV1(@ModelAttribute Item item, BindingResult bindingResult, RedirectAttributes redirectAttributes, Model model) {

    //검증에 실패하면 다시 입력 폼으로
    if (bindingResult.hasErrors()) {
        log.info("errors={} ", bindingResult);
        //model.addAttribute("item", item)<<자동추가되는거아님? 
        return "validation/v2/addForm";
    }

V1,V2 모두 @ModelAttribute 애노테이션에 의해서 model.addAttribute("item", item) 이 추가 된 후 item이 addForm으로 넘어가서 둘 다 값이 유지 돼야 된다고 생각 하는데.........

제가 어디서 놓치고 있는지 모르겠습니당 ㅠㅠ

MVC spring

답변 1

1

OMG

안녕하세요. g g님, 공식 서포터즈 OMG입니다.
.

model에 errors를 담아야 errors에서 key값이 포함되어 있는지 확인하여 해당 value를 출력합니다.

<div class="field-error" th:if="${errors?.containsKey('itemName')}" th:text="${errors['itemName']}">
    상품명 오류
</div>

V1에서는 model에 errors를 담지만, V2에서는 없어서 그런거 같아요


.
감사합니다.

0

g g

1 .

<input type="text" id="price" th:field="*{price}"// <<*{price} 이 부분이  
       //model.addAttribute("item", item) 여기서 넘어온 값이 채워지는 부분인데
       //"model에 errors를 담아야 errors에서 key값이 포함되어 있는지 확인하여 해당 value를 출력합니다."
       //erros랑 상관 없지 않나요?
       th:class="${errors?.containsKey('price')} ? 'form-control field-error' : 'form-control'"
       class="form-control" placeholder="가격을 입력하세요">
<div class="field-error" th:if="${errors?.containsKey('price')}" th:text="${errors['price']}">
    가격 오류
</div>

 

2.

"V1에서는 model에 errors를 담지만, V2에서는 없어서 그런거 같아요"

그냥 그런가 보다 하고 넘어가도 될까요?

0

OMG

안녕하세요. g g님, 공식 서포터즈 OMG입니다.

 

제가 답변을 잘못드렸었네요.

이전 답변은 무시하시고, 답변을 새로 드리겠습니다.

답변 이후 시간이 조금 지나 이후 강의를 수강하셨을 수 있을 것 같은데요.

힌트이자 정답을 드릴테니 확인해보셨으면 좋겠습니다.

우선 말씀하신대로 동작하는게 맞습니다.

대신 비교 대상을 이전 버전과 비교하지말고 다음 버전 메서드와 비교해보셨음 하고,

public String addItemV2()

 

FieldError의 생성자 파라미터 수가 다른 것을 확인해보시고(30분 정도), 해결이 안될 경우 댓글남겨주세요^^

0

OMG

bindingResult.addError(new FieldError("item", "itemName", "상품 이름은 필수 입니다."));

 

bindingResult.addError(new FieldError("item", "itemName", item.getItemName(), false, null, null, "상품 이름은 필수 입니다."));

0

g g

주말에도 답변 달아주셔서 너무 너무 감사하고 죄송스럽네요 치킨이라도 사드리고 싶다는ㅎㅎ;

 

1. 일단 OMG님 답변의 의도는

이번 강의 V2 addItemV1에서 잘못 입력했을 때 값이 유지 되지 않아서 다음 강의 V2 addItemV2가 나왔고 addItemV2에 파라미터를 추가 해줌으로서 잘못 입력했을 때 값이 유지된다는 것을 말씀 하신 것이 맞나요?

 

2.그런데 제가 궁금한 것은 9:09초 쯤 인데요

V1 addItem ,V2 addItemV1 둘 다

//model.addAttribute("item", item) 

이 로직이 (@ModelAttribute Item item)에 의해서 자동으로 추가된다고 말씀하셨는데 잘못 입력했을 때 V1 addItem은 item값을 넘겨 받아서 유지가 되고 왜 V2 addItemV1은 item값을 넘겨 받지 못 하는 지가 궁금합니다

 

 

V1 addItem

@PostMapping("/add")
public String addItem(@ModelAttribute Item item, RedirectAttributes redirectAttributes, Model model) {
    //검증에 실패하면 다시 입력 폼으로
    if (!errors.isEmpty()) {
        log.info("errors = {} ", errors);
        model.addAttribute("errors", errors);
         //model.addAttribute("item", item)<<자동추가되는거아님? 
        return "validation/v1/addForm";
    }
/성
}

V2 addItem1

@PostMapping("/add")
public String addItemV1(@ModelAttribute Item item, BindingResult bindingResult, RedirectAttributes redirectAttributes, Model model) {
    //검증에 실패하면 다시 입력 폼으로
    if (bindingResult.hasErrors()) {
        log.info("errors={} ", bindingResult);
         //model.addAttribute("item", item)<<자동추가되는거아님? 
        return "validation/v2/addForm";
    }

}

3

OMG

치킨 말고 영한님에게 힘이되는 수강평이 저한테 있어서 더 감사할 것 같습니다 ^^

 

1.

네 그런 의도로 말씀드린게 맞습니다.

2.

저도 그 부분이 의아해서 이전 답변 드리기전 실제 디버깅으로 model에 담긴 값들을 확인해보았는데요,

값이 담겨 있기는 합니다.

ValidationItemControllerV1.addItem()

image

ValidationItemControllerV2.addItemV1()

image

 

ValidationItemControllerV2.addItemV2()

image

addItem(), addItemV1(), addItemV2() 까지 모두 에러가 발생하는 상황에서 addForm으로 돌아갈 때 model에 실패하는 값들을 갖고 있기는 했습니다.

addItemV1()에서 itemName, price, quantity 모두 값 2를 포함하고 있는데요.

ValidationItemControllerV2로 변경되면서 추가된게 BindingResult인 만큼 BindingResult의 구현체에서 값을 덮어씌우지 않나 예상합니다.

addItemV1()에서 생성하는 FieldError는 다음과 같이 rejectValue가 Null로 자기 자신을 호출하는데,

image

image

bindingResult.addError(new FieldError())

rejectValue가 null인 상태에서 addError의 로직에서 기존 model의 item에 있는 데이터보다 우선순위가 높다거나, 덮어씌우는 등의 처리로 인해 발생하지 않나 예상되네요.

 

실제 구현코드 까지 보면 조금 더 정확히 알 수 있을 것 같은데요,

강의에서 구현 클래스를 언급하시는데요(BeanPropertyBindingResult)

궁금하시다면 한번 확인해보셔도 좋을 것 같아요. 처음 질문 주실 때

제가 어디서 놓치고 있는지 모르겠습니당 ㅠㅠ

라고하셨는데요,

제 생각에는 놓쳤다기 보다는 강의보다 깊게 파고 들어가신게 아닌가 싶을 정도로 예리하고 좋은 학습태도이지 않나 싶네요 ㅎㅎ

 

제 답변 + 확인해보신 내용을 바탕으로 궁금하신게 있다면 추가적으로(본 링크를 포함하셔도 됩니다.) 글 남겨주시면 영한님이나 서포터즈가 답변을 드릴 수 있을 것 같습니다.

 

0

g g

와 이렇게 자세하게 답변해 주시다니 너무 감동입니다..ㅠㅠ

감기조심하세요~

 

1

11 1

헉 이거 질문하려고 했는데 좋은 질문과 답변이 이미 있었군요

감사합니다

이미지 업로드와 db 트랜잭션 묶는법

0

43

1

Could not resolve org.springframework.boot:spring-boot-starter-validation:2.4.4

0

53

2

MessageSourceTest 코드

0

49

1

인터셉터 에러 설정

0

48

1

resolveArgument()메서드 질문

0

57

1

43강 검증1 에서 실패 로직 관련 질문있습니다.

0

58

2

타임리프 3.X 버전 rendering, serializer 에러 해결 방법

2

133

3

스프링 빈에 등록이 안되는거 같은데 어떻게 하면 좋을까요?ㅠㅠ

0

90

3

pdf 오타 문의

0

57

1

ItemUpdateForm 검증 관련 질문입니다.

0

49

1

22page 링크 주소 변경

0

59

2

특정 데이터와 파일을 함께 저장 시, 테이블 구조 질문

0

53

1

섹션3번 수업에 대한 질문입니다.

0

80

2

@Autowired 보다 더 좋은 방법이 어떤 걸까요?

0

85

2

타입컨버터 가 람다랑 비슷해 보이는데 저의 생각이 맞는지?.

0

66

1

자바스크립트 인라인에서 객체 직렬화 시 오류가 납니다

0

142

3

스프링부트 - 오류페이지2 에서 500.html 에서 쓰인 객체 질문

0

63

1

톰캣 에러 페이지가 안보입니다.

0

104

2

apiEceptionController에서 센드 에러 호출하면 안되는지?

0

81

1

세션 타임아웃시 쿠키 삭제 방법이 없나요?

0

118

2

ApiExceptionController 질문드립니다.

0

64

1

셀렉박스 챕터에서 option value에 ==배송 방식 선택== 이것을 넣은 이유가 궁금함, 이렇게 구상해도 되는지?

0

66

1

MemberRepository 필드의 fianl 선언 유무

0

85

2

혹시 index.html 에서는 fragment 사용이 안되는건가요

0

58

1