MVC 패턴
컨트롤러에서는 model에서 데이터를 가져와 이를 뷰에 전달한다. 이를 MVC 패턴이라고 한다.
Controller
1) HomeController 예시
HomeController.java
package jpabook.jpashop.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@Slf4j // logger 생성: Logger log = (Logger) LoggerFactory.getLogger(getClass());
public class HomeController {
@RequestMapping("/")
public String home(){
log.info("Home Page");
return "home";
}
}
컨트롤러를 사용할 때에는 @Controller 어노테이션을 사용한다. 위의 예시에서 @Slf4j라는 어노테이션을 사용하였는데 이는 log를 찍기 위한 어노테이션으로 롬복에서 따로 지원하는 어노테이션이다. 만일 @Slf4j 어노테이션을 사용하지 않고 log를 찍기위해선 주석처럼 별도로 선언해서 사용하면 된다.
결과적으로 "localhost:8080/"에 접속하면 home()이 실행되고 그 결과 log에 "Home Page"가 찍히고 "localhost:8080/"에 home.html이 뿌려진다.
2) MemberController 예시
MemberController.java
package jpabook.jpashop.controller;
import jpabook.jpashop.domain.Member;
import jpabook.jpashop.service.MemberService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
@RequiredArgsConstructor
@Slf4j
public class MemberController {
private final MemberService memberService;
// Get: 클라이언트에서 서버로 어떠한 리소스로부터 정보를 요청하는 메서드
@GetMapping("/members/new") //@RequestMapping(value = "/members/new", method = "RequestMethod.GET)
public String createForm(Model model) {
// model 객체: Controller에서 생성한 데이터를 담아서 View로 전달할 때 사용하는 객체.
model.addAttribute("memberForm", new MemberForm());
// memberForm이라는 이름으로 MemberForm 객체가 전달됨
log.info("Create Member");
return "members/createMemberForm";
}
}
MemberController도 HomeController와 비슷하다. "localhost:8080/members/new"에 접속하면 createForm()이 실행되고, 그 결과 model을 파라미터로 받아서 model.addAttribute("memberForm", new MemberForm())을 실행한다.
여기서 MemberForm은 회원 정보를 담기위한 클래스이다.
MemberForm.java
package jpabook.jpashop.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;
}
model.addAttribute에 의해서 MemberForm 객체는 "memberForm"이라는 이름으로 "members/createMemberForm.html" 에 전달된다. 그 결과 화면에서 memberForm 객체에 접근할 수 있게된다.
members/createMemberForm.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="fragments/header :: header" />
<style>
.fieldError {
border-color: #bd2130;
}
</style>
<body>
<div class="container">
<div th:replace="fragments/bodyHeader :: bodyHeader"/>
<form role="form" action="/members/new" th:object="${memberForm}"
method="post">
<div class="form-group">
<label th:for="name">이름</label>
<input type="text" th:field="*{name}" class="form-control"
placeholder="이름을 입력하세요"
th:class="${#fields.hasErrors('name')}? 'form-control fieldError' : 'form-control'">
<p th:if="${#fields.hasErrors('name')}"
th:errors="*{name}">Incorrect date</p>
</div>
<div class="form-group">
<label th:for="city">도시</label>
<input type="text" th:field="*{city}" class="form-control"
placeholder="도시를 입력하세요">
</div>
<div class="form-group">
<label th:for="street">거리</label>
<input type="text" th:field="*{street}" class="form-control"
placeholder="거리를 입력하세요">
</div>
<div class="form-group">
<label th:for="zipcode">우편번호</label>
<input type="text" th:field="*{zipcode}" class="form-control"
placeholder="우편번호를 입력하세요">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<br/>
<div th:replace="fragments/footer :: footer" />
</div> <!-- /container -->
</body>
</html>
html을 보면 th: 뭐시기 이런애들이 있는데 여기서 th:는 thymeleaf의 문법이다.
여기서 몇가지만 보면 <form th: object = "${memberForm}">을 보면 'th: object = "${memberForm}" ' 이라는 어트리뷰트를 볼 수 있다. 이는 <form><form/> 내부에서 우리가 넘긴 "memberForm"이라는 객체를 사용할 것이라는 의미이다.
th:field 라는 어트리뷰트도 있다. 예컨데 th:field = "*{name}"이라는 어트리뷰트는 id = "name" name = "name"과 같은 의미이다.(솔직히 잘모르겠다).
// 위아래는 동일 코드
<input type="text" th:field="*{city}" class="form-control" placeholder="도시를 입력하세요">
<input type="text" class="form-control" placeholder="도시를 입력하세요" id="city" name="city" value="">
@GetMapping과 @PostMapping
-@GetMapping
GetMapping은 return 값으로 화면에 보일 뷰(html)의 경로를 반환한다.
ex) return "memberList.html"
-@PostMapping
PostMapping은 return 값으로 이동할 url 주소를 반환한다.
ex) return "redirect:/"
'Spring > SpringBoot' 카테고리의 다른 글
SpringBoot- @Valid, @ResponseBody, @RequestBody (0) | 2023.06.28 |
---|---|
SpringBoot- @GetMapping, @PostMapping (0) | 2023.06.28 |
SpringBoot- @Transactional (0) | 2023.06.22 |
SpringBoot- 테스트 케이스 작성 예시 (0) | 2023.06.20 |
SpringBoot- EntityManager 생성법 (0) | 2023.06.20 |