폼 객체를 사용해서 화면 계층과 서비스 계층을 명확하게 분리합니다.
package jpabook.jpashop.controller;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotEmpty;
@Getter @Setter
public class MemberForm {
@NotEmpty(message = "회원 이름은 필수 입니다.") //...1
private String name;
private String city;
private String street;
private String zipcode;
}
@NotEmpty
→ 검증 어노테이션 (Bean Validation) 자세히
이름은 필수로 받아야 한다고 정해두는 어노테이션
javax.validation을 통해서 스프링이 validation을 해줍니다.
Validation?
validation이란 어떤 데이터의 값이 유효한지, 타당한지 확인하는 것을 의미합니다.
예를들어 이메일 주소 양식은 [email protected]인데, 회원 가입을 할 때 이메일 양식이 일치하지 않으면 유효하지 않은 이메일이므로 회원 가입을 막을 수 있습니다.
만약 값이 비어있다면 오류가 발생합니다.
<aside>
❗ @NotEmpty 어노테이션은 build.gradle에서 implementation 'org.springframework.boot:spring-boot-starter-validation'
의존성이 없다면 동작하지 않습니다.
</aside>
<aside> ❗ form, DTO 차이
사실 Form이나 DTO나 모두 단순히 계층간에 데이터를 전달할 때 사용합니다. 그래서 둘의 역할은 똑같습니다.
다만 form이라는 것은 제약을 더 두어서 명확하게 컨트롤러 까지만 사용해야 한다는 의미를 강하게 두었습니다.
form이라는 것 자체가 웹 기술에 종속적인 단어이니까요.
DTO이름 그대로 데이터 전송 객체인데, 더 범용적으로 사용되는 단어라 생각하시면 됩니다.
DTO는 어디에 정의해두는가에 따라 다르겠지만, 서비스에서도 사용할 수 있고, 리포지토리에서도 사용할 수 있습니다.
</aside>
package jpabook.jpashop.controller;
import jpabook.jpashop.service.MemberService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
@RequiredArgsConstructor
public class MemberController {
private final MemberService memberService;
@GetMapping("/members/new")
public String createForm(Model model) { //...1
model.addAttribute("memberFrom", new MemberForm());
return "members/createMemberForm"; //...2
}
}
컨트롤러가 createMemberForm로 화면을 이동할 때 MemberForm이라는 빈 껍데기 객체를 가지고 갑니다.
가지고 가는 이유는 Validation 같은 것을 해주기 때문에 빈 껍데기라도 가지고 갑니다.
위에서 MemberForm 객체에 @NotEmpty 처럼 validation을 했습니다.