실제 베이스 코드를 기반으로 화면을 하나씩 만들어 가는 과정이다. 실제 동작하는 화면을 만드는 과정이다.
참고: Hierarchical-style layouts 예제에서는 뷰 템플릿을 최대한 간단하게 설명하려고,
header
,footer
같은 템플릿 파일을 반복해서 포함한다. 링크 Hierarchical-style layouts을 참고하면 이런 부분도 중복을 제거할 수 있다.
이쁜 디자인을 위해 부트스트랩을 사용. (v4.3.1) (https://getbootstrap.com/)
resources/static
하위에 css
, js
추가resources/static/css/jumbotron-narrow.css
추가복붙은 바로 인식되지 않을 경우가 있음. 싱크라이저 해주고, 필드 프로젝트 해주면 인식해줌.
package com.jpabook.jpashop.domain.controller;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotEmpty;
@Getter @Setter
public class MemberForm {
@NotEmpty(message ="회원이름은 필수 잆니다.")
private String name;
private String city;
private String street;
private String zipcode;
}
김영한님은 해당 코드의 어노테이션을 썻는데 나는 왜 해당 어노테이션을 못 쓰는 것일까???
→ @NotEmpty
어노테이션을 사용할 수 없는 문제는 일반적으로 다음 중 하나의 이유 때문에 발생한다.
의존성 누락: @NotEmpty
는 Java Bean Validation API의 일부입니다. 이 어노테이션을 사용하기 위해서는 hibernate-validator
라이브러리나 유사한 Bean Validation 구현체가 프로젝트의 의존성에 포함되어 있어야 합니다. pom.xml
(Maven을 사용하는 경우) 또는 build.gradle
(Gradle을 사용하는 경우) 파일에서 해당 의존성을 추가해야 합니다.
Maven을 사용하는 경우
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.5.Final</version>
</dependency>
Gradle을 사용하는 경우
implementation 'org.hibernate:hibernate-validator:6.1.5.Final'
잘못된 임포트: @NotEmpty
어노테이션을 사용할 때 올바른 패키지를 임포트했는지 확인하세요. 이 어노테이션은 javax.validation.constraints.NotEmpty
에 위치합니다. 다른 패키지의 NotEmpty
를 임포트했다면 오류가 발생할 수 있습니다.
IDE 설정 문제: 때때로, 사용하는 개발 환경(IDE)가 의존성을 제대로 감지하지 못할 수 있습니다. 이 경우, 프로젝트를 다시 빌드하거나 IDE를 재시작해 보세요.
package com.jpabook.jpashop.domain.controller;
import com.jpabook.jpashop.domain.entity.Address;
import com.jpabook.jpashop.domain.entity.Member;
import com.jpabook.jpashop.domain.service.MemberService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
@RequiredArgsConstructor
public class MemberController {
private final MemberService memberService;
@GetMapping("/members/new")
public String createForm(Model model) {
model.addAttribute("memberForm", new MemberForm());
return "members/createMemberForm";
}
@PostMapping("/members/new")
public String create(@Valid MemberForm form, BindingResult result) { // BindingResult를 써서 어떤 에러가 떳는지 에러 페이지를 띄워줌.
// 오류가 원래 팅겨버리고, 이 컨트롤러에서 코드가 안 넘어가고 Validate한 다음에 BindingResult를 해주면 오류가 담겨서 실행해짐.
// @valid 라고 적어주면 폼에 이름이 무조건 들어와야함.
if (result.hasErrors()) {
return "members/createMemberForm";
}
Address address = new Address(form.getCity(), form.getStreet(), form.getZipcode());
Member member = new Member();
member.setName(form.getName());
member.setAddress(address);
memberService.join(member);
return "redirect:/"; // 리다이렉트로 홈으로 보내버림
}
}