[Spring Intro] Section 05. 회원 관리 예제 - 웹 MVC 개발
강의: 김영한의 스프링 입문
# 회원 웹 기능 - 홈 화면 추가
1. 홈 컨트롤러 추가
- java/hello/hellospring/controller/HomeController.java를 다음과 같이 작성한다
- @GetMapping("/")에서 "/"는 처음의 도메인(localhost:8080) 경로를 의미한다
- return "home"; 구문은 template 내의 home.html을 찾아 반환하는 역할이다
package hello.hellospring.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HomeController {
@GetMapping("/")
public String home(){
return "home";
}
}
2. 회원 관리용 홈
- resources/templates/home.html을 다음과 같이 작성한다
- 회원을 등록하고 조회할 수 있는 기능을 보여주는 페이지이다
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div class="container">
<div>
<h1>Hello Spring</h1> <p>회원 기능</p>
<p>
<a href="/members/new">회원 가입</a> <a href="/members">회원 목록</a>
</p>
</div>
</div> <!-- /container -->
</body>
</html>
3. 실행
- 홈 컨트롤러와 홈 html을 추가한 후 실행하면 다음과 같이 페이지가 띄워진다
4. 컨트롤러 vs 정적 파일
- static의 index.html 화면이 아닌 home.html이 띄워지는 이유는 컨트롤러가 정적 파일보다 우선순위가 높기 때문이다
- 지난 포스팅의 내용을 참고하면 된다 - 정적 컨텐츠 부분을 참고한다
- 내장 톰캣 서버는 스프링 컨테이너에서 관련 컨트롤러가 있는지 먼저 찾고 없다면 static 파일을 찾는다
- 현재 HomeController에서 매핑된 home화면이 있기 때문에 해당 화면을 호출하는 것이다
# 회원 웹 기능 - 등록
1. 회원 등록 폼 개발 - 회원 등록 폼 컨트롤러
- java/hello/hellospring/controller/Membercontroller.java에 다음과 같이 코드를 추가한다
package hello.hellospring.controller;
import hello.hellospring.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class MemberController {
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService){
this.memberService = memberService;
}
// 여기서부터 추가한다
@GetMapping(value = "/members/new")
public String createFrom(){
return "members/createMemberForm";
}
}
2. 회원 등록 폼 개발 - 회원 등록 폼 HTML
- resources/templates 아래 members라는 폴더를 생성한다
- 생성한 members 폴더 아래 다음과 같이 createMemberFrom.html을 작성한다
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div class="container">
<form action="/members/new" method="post">
<div class="form-group">
<label for="name">이름</label>
<input type="text" id="name" name="name" placeholder="이름을 입력하세요">
</div>
<button type="submit">등록</button> </form>
</div> <!-- /container -->
</body>
</html>
3. 회원 등록 컨트롤러 - 웹 등록 화면에서 데이터를 전달받을 폼 객체
- java/hello/hellospring/controller/MemberForm.java를 다음과 같이 작성한다
package hello.hellospring.controller;
public class MemberForm {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
4. 회원 등록 컨트롤러 - 회원 컨트롤러에서 회원을 실제 등록하는 기능
- java/hello/hellospring/controller/MemberController.java에 다음과 같이 코드를 추가한다
package hello.hellospring.controller;
import hello.hellospring.domain.Member;
import hello.hellospring.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import javax.swing.text.html.Option;
import java.util.Optional;
@Controller
public class MemberController {
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService){
this.memberService = memberService;
}
@GetMapping(value = "/members/new")
public String createFrom(){
return "members/createMemberForm";
}
// 여기서부터 추가
@PostMapping(value = "/members/new")
public String create(MemberForm form){
Member member = new Member(); // 새로운 멤버 생성
member.setName(form.getName()); // form으로부터 getName
memberService.join(member); // 생성한 Member를 회원가입 시킴
return "redirect:/"; // 회원가입이 끝나면 홈으로 리다이렉트
}
}
5. 회원 등록 확인
- 홈 화면에서 회원 가입 클릭을하면 localhost:8080/members/new로 이동한다
- 주어진 textbox에 이름을 spring으로하고 등록 버튼을 누르면 다시 메인 페이지로 리다이렉트 된다
- 이때 멤버가 저장되는 것을 확인하기 위해서 MemberController.java에 create method 내에 다음과 같은 코드를 추가한다
@PostMapping(value = "/members/new")
public String create(MemberForm form){
Member member = new Member();
member.setName(form.getName());
memberService.join(member);
// 현재 사용되는 memberService 내의 MemberRepository는 SpringConfig.java에 의해 memoryMemberRepository를 호출하므로 그 안에 선언된
// store 이름을 가지는 Map에 현재 생성한 member가 잘 저장되었는지를 확인한다
System.out.println("member =" +memberService.findOne(member.getId()).get().getName());
return "redirect:/";
}
6. 회원 등록 원리
- http://localhost:8080/members/new에 접속하면 다음과 같은 화면이 호출된다
- 이때 사용되는 방식은 GET 방식이며 memberController 내에서 ("/members/new")에 매핑되는 createForm 메서드가 호출된다
- viewResolver에 의해 createForm이 선택되고, thymeleaf 템플리 엔진이 return 코드에서 반환되는 members/createMemberForm(templates/members/createMemberForm.html)을 랜더링 하여 화면에 보여준다
- 해당 페이지에서 이름을 spring으로 입력하고 등록 버튼을 누르면 POST 방식으로 입력한 name이 넘어가게 된다
- createMemberForm.html을 확인해 보면 값을 입력하는 form 태그 내의 input 태그에서 name = "name"을 확인할 수 있다
- "name" 부분은 서버로 넘어올 때, key 역할을 한다
- 즉, 컨트롤러 패키지 아래에 있는 MemberForm에 선언된 변수 name과 매핑되고 있어 입력한 값이 name으로 전달되는 것이다
- 등록 버튼을 누를 시 <form action = "/member/new" method="post">에 의해 action에 적힌 url에 POST 방식으로 입력한 값이 넘어가게 된다
- memberControlller에서 @Postmapping되어 있는 create() method를 호출한다
- MemberForm의 setName()은 아까 form 태그를 통해 전달된 이름을 name에 저장하는 역할을 한다
- MemberForm의 getName()을 통해 MemberController 내 create() 함수에서 등록할 member의 이름을 지정해 줄 수 있다
- 이렇게 생성된 member를 memberService의 join method를 통해 회원 가입시키고 페이지를 다시 홈 화면으로 리다이렉트 시키는 것이다
주로 데이터를 조회할 때는 GET method를, 데이터를 전달(등록)할 때는 POST method를 사용한다
# 회원 웹 기능 - 조회
1. 회원 컨트롤러에서 조회 기능
- java/hello/hellospring/controller/MemberController.java에 아래 코드를 추가한다
- model.addAttribute를 통해 HTML에서 사용하는 thymeleaf 엔진에서 members List를 사용할 수 있게 된다
import org.springframework.ui.Model;
...
@GetMapping(value = "/members")
public String list (Model model){
List<Member> members = memberService.findMembers();
model.addAttribute("members",members);
return "members/memberList";
}
2. 회원 리스트 HTML
- resources/templates/members/memberList.html에 다음 코드를 작성한다
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div class="container">
<div>
<table>
<thead>
<tr>
<th>#</th>
<th>이름</th> </tr>
</thead>
<tbody>
<tr th:each="member : ${members}">
<td th:text="${member.id}"></td>
<td th:text="${member.name}"></td>
</tr>
</tbody>
</table>
</div>
</div> <!-- /container -->
</body>
</html>
3. 회원 조회 실행 및 원리
- http://localhost:8080으로 접속한 후 회원 목록을 클릭하면 회원 목록을 보여주는 페이지가 뜨는 것을 확인할 수 있다
- 앞서 만든 회원 가입 기능으로 spring1, spring2를 등록한다
- 회원 목록을 확인하는 페이지를 클릭하면 thymeleaf가 동작하게 된다
- 현재 members를 보여주는 페이지는 members/memberList.html이다
- memberList.html에는 thymeleaf 템플릿 엔진의 문법인 th:each가 사용되어 있고 이는 MemberController의 list method에서 model로 넘겨준 members에 대해 루프를 돌며 members에 저장된 객체에 대한 정보를 가져와 테이블로 표현한다
- thymeleaf에서 ${}로 표시된 내용들은 model에 저장된 값들을 가져올 수 있게 해 준다
- list method에서는 memberservice를 통해 모든 회원에 대한 리스트를 members로 저장하고, model.addAttribute를 사용하여 members를 템플릿 엔진(=thymeleaf)에서 활용할 수 있게 한다
- 현재는 AttributeName이 members, value로 회원 전체에 대한 List를 가지는 데이터를 model이 저장하고 있는 것이다
- 이때, 각 member의 id와 name은 private로 정의되어 있으므로 Property 방식(Getter/Sette를 통한 접근)으로 데이터를 불러온다
- 즉, 해당 페이지에 접근하면 스프링은 /member와 관련된 컨트롤러(=MemberController)를 찾아 매핑되는 method(=list)를 실행한다
- 실제 랜더링된 페이지의 소스코드를 확인하면 HTML로 테이블 내에 두 개의 행이 생성되어 있음을 확인할 수 있다
현재 우리는 메모리에 저장하는 방식을 사용했기 때문에 서버를 종료하고 재실행하면 저장했던 데이터들이 모두 사라진다.
실무에서는 이런 일이 발생하면 안 되므로 데이터베이스를 사용한다
'Study > Backend Note' 카테고리의 다른 글
[Spring Intro] Section 07. AOP (0) | 2023.03.07 |
---|---|
[Spring Intro] Section 06. 스프링 DB 접근 기술 (0) | 2023.03.06 |
[Spring Intro] Section 04. 스프링 빈과 의존관계 (0) | 2023.02.28 |
[Spring Intro] Section 03. 회원 관리 예제 - 백엔드 개발 (0) | 2023.02.28 |
[Spring Intro] Section 02. 스프링 웹 개발 기초 (0) | 2023.02.26 |