purplely88's home

시작에 앞서

9장을 완료해주세요.

 

데이터 바인딩 개요

데이터 바인딩이란 화면 입력항목과 오브젝트 필드와의 맵핑을 뜻합니다.

또한, 화면으로부터 전달받은 값을 필드 데이터형에 맞춰서 변환도 해줍니다.

 

스프링에서는 데이터 바인딩을 어느 정도 자동으로 시행해줍니다.

예를 들어, 화면에서 텍스트 항목에 입력한 수치를 오브젝트의 int형으로 변환해줍니다.

대신, 데이터 형 변환이 어려울 경우도 있습니다. 그런 경우에는 어노테이션을 사용하는 것으로 데이터 바인딩을 할 수 있습니다. 

어떤 방식으로 쓰는 거에는 이다음 실제 예를 들어서 설명하겠습니다.

 

데이터 바인딩 코딩

그러면 실제로 만들어보겠습니다.

데이터 바인딩에 필요한, 화면에서 컨트롤러 클래스에 오브젝트를 넘기는 방법에 대해서 배우겠습니다.

만들기 전에, 먼저 처리 개요에 대해서 설명하겠습니다.

로그인 화면에서는 아무것도 하지 않기 때문에, 유저 등록 화면의 처리 개요를 보도록 하겠습니다.

 

1,2의 처리

로그인 화면에서 유저 등록 화면으로 전이합니다. 그때에 유저 등록용 폼 클래스의 인스턴스(SignupForm)를 화면에 전달합니다.

 

3,4,5의 처리

유저 등록 버튼을 클릭하면, 폼 클래스의 인스턴스를 컨트롤러 클래스에 전달합니다.

폼 클래스의 인스턴스를 받은 후에는 /login에 리다이렉트 합니다.

유저 등록은 이루어지지 않습니다. 

(실제 등록은 데이터 베이스 쪽에서 다루겠습니다.)

 

즉, 유저 등록 화면에서 유저 등록용 폼 클래스에 데이터 바인딩을 합니다.

먼저 폼 클래스를 작성해보도록 하겠습니다. 

 

SignupForm.java

 

 

포인트 1

@DateTimeFormat 어노테이션을 필드에 붙임으로써, 화면으로 전달받은 문자열을 날짜 형식으로 변환해줍니다.

또한, pattern속성에 어떤 포맷으로 데이터를 전달받을지를 지정합니다.

 

데이터 바인딩용 어노테이션 @DateTimeFormat 외에도 @NumberFormat이라는 어노테이션이 있습니다.

사용방법은 구글링 하시면 쉽게 아실 수 있으십니다.

 

다음은 화면에서 전달받은 폼 클래스를 컨트롤러 클래스에서 받을 수 있도록 해보겠습니다.

 

SignupController.java

 

포인트 1

인수 폼 클래스에 @ModelAttribute 어노테이션을 붙임으로써, 자동으로 Model 클래스에 등록(addAttribute)해줍니다.

즉, 아래의 내용과 같습니다.

 

@GetMapping("/signup")

public String getSignUp(SignupForm form, Model model) {

  // 폼 클래스를 Model에 등록

  model.addAttribute("SignupForm", form);

}

 

또한, @ModelAttribute를 붙일 경우, 디폴트 값으로는 클래스 명의 앞글자가 소문자로 바꾼 문자열이 키 명으로 등록됩니다.

샘플 코드의 경우에는 "signupForm"이라고 하는 키 명에 등록됩니다.

혹시나 키 명을 바꾸고 싶을 경우에는 @ModelAttribute("<키명>")과 파라미터를 지정합니다.

 

포인트 2

데이터 바인딩 결과를 받을 경우에는 메서드의 인수에 BindingResult 클래스를 추가합니다.

이 클래스의 hasError() 메서드에 데이터 바인딩에 실패했는지를 알 수 있습니다.

또한, 이후에 등장할 밸리데이션(입력 체크)에 에러가 발생할 경우에도 이 BindingResult 클래스의 hasError() 메서드에 실패했는지 알 수 있습니다.

 

포인트 3

데이터 바인딩에 실패할 경우에는 BindingResult의 hasError() 메서드에 false가 반환됩니다.

위 코드에서는 데이터 바인딩에 실패했을 경우, 유저 등록 화면으로 돌아옵니다.

그 경우에는 getSignUp 메서드를 호출하고 있습니다.

이유는 라디오 버튼용 변수를 초기화해주기 때문입니다.

 

다음으로 유저 등록용 html을 수정합니다.

 

포인트 1

th:object 속성을 사용함으로써, Model에 등록된 오브젝트를 받는 것이 가능합니다.

위 코드로 말하자면, SignupForm 클래스를 받고 있습니다.

 

사용 방법은 다음과 같습니다.

th:oject="${<ModelAttribute의 키 명>}"

 

th:object를 붙인 태그 안에는 th:field에 그 오브젝트명을 생략할 수 있습니다.

th:field를 사용하면, 오브젝트 안에 필드를 취득할 수 있습니다.

 

th:field 사용법 첫 번째

th:field="${<ModelAttribute의 키 명. 필드명>}"

이것은 th:object속성을 쓰지 않았을 경우의 사용법입니다. 이 방법으로 위 코드를 다시 작성해본다면 아래와 같습니다.

th:field="${signupForm.userId}"

 

필드가 하나밖에 사용되지 않을 경우에는 th:object를 작성하지 않아도 값을 취득, 송신이 가능하다는 것입니다.

 

th:field 사용법 두 번째

th:field="${<필드명>}"

th:object가 붙은 태그 안에 있으면, 오브젝트 명을 생략할 수 있습니다.

이것은 위 코드와 같은 방법입니다. 화면에서 보낼 필드가 많을 경우에 유효한 방법입니다.

종래 필드가 늘 수 있다는 생각을 한다면 이 방법을 추천합니다.

 

포인트 2

에러 메시지를 정리해서 일람 표시하기 위해서는 라디오 버튼과 같은 th:each 속성을 사용합니다.

정리하지 않고 개별 메시지로 표시하는 방법에 대해서는 밸리데이션(입력 체크)에서 설명하겠습니다.

 

실행

스프링 부트를 실행하신 다음에 신규 등록 화면으로 들어오셔서 등록 정보를 입력합니다.

정상 등록일 시 로그인화면으로 전이
컨트롤러 클래스에서 작성한 println 내용

이것으로 두 가지가 가능해졌습니다.

1. 화면에서 폼 클래스에 값을 전달한다.

2. 폼 클래스를 컨트롤러 클래스에 전달한다.

 

하지만, 또 문제가 있습니다.

데이터 바인딩에 실패했을 경우입니다. 

예를 들어, 연령에 문자열이 입력되어 있다던지, 생일에 연도만 입력해보겠습니다.

 

이대로라면 메시지가 영어이면서 내용도 적절치 않습니다.

다음으로 에러 메시지를 수정해보도록 하겠습니다.

'프로그래밍 > 스프링 부트' 카테고리의 다른 글

9. 데이터 바인딩 & 밸리데이션 (1/4)  (0) 2020.06.20
8. DI (4/4)  (0) 2020.06.18
7. DI (3/4)  (0) 2020.06.16
6. DI (2/4)  (0) 2020.06.16
5. DI (1/4)  (0) 2020.06.14