(Spring Rollout) 섹션 05. 회원 관리 샘플 – 웹 MVC 개발
강의: 김영한의 봄 소개
# 회원 웹 기능 – 홈 화면 추가
1. 홈 컨트롤러 추가
- 다음과 같이 java/hello/hellospring/controller/HomeController.java를 작성합니다.
- @GetMapping(“/”)에서 “/”는 첫 번째 도메인(localhost:8080)의 경로를 나타냅니다.
- return home”; 구문은 템플릿 내에서 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="http://fascination-euna.members/new">회원 가입</a> <a href="http://fascination-euna.members">회원 목록</a>
</p>
</div>
</div> <!-- /container -->
</body>
</html>
3. 달리기
- 홈 컨트롤러와 홈 html을 추가한 후 실행하면 이렇게 페이지가 열립니다.


4. 컨트롤러 대 정적 파일
- 정적인 index.html 화면 대신 home.html이 나오는 이유는 컨트롤러가 정적인 파일보다 우선순위가 높기 때문입니다.
- 저번 포스팅 내용 참고하시면 됩니다 – 정적 내용 부분 참조
(Spring 소개) Section 02. Spring 웹 개발 기초
(Spring Intro) Section 02. Spring Web Development Basic Lecture: Introduction to Spring by Kim Younghan # Spring Web Development Basics Static Content: 웹 브라우저에서 파일을 그대로 다운로드 MVC 및 Template Engine: 서버에서 HTML 생성
매혹-euna.tistory.com
- 내장된 Tomcat 서버는 먼저 Spring 컨테이너에서 관련 컨트롤러를 찾고 그렇지 않은 경우 정적 파일을 찾습니다.
- 현재 HomeController에 시작 화면이 나타나므로 해당 화면을 불러옵니다.
# 회원을 위한 웹 기능 – 등록
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 = "http://fascination-euna.members/new")
public String createFrom(){
return "members/createMemberForm";
}
}
2. 회원가입 양식 개발 – 회원가입 양식 HTML
- “Resources/Templates” 아래에 “Members”라는 폴더를 만듭니다.
- 생성된 구성원 폴더에 다음과 같이 createMemberFrom.html을 작성합니다.
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div class="container">
<form action="http://fascination-euna.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. Member Registration Controller – 웹 등록 화면에서 데이터를 받기 위한 Form 객체
- 다음과 같이 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. Member Registration Controller – Member Controller에 실제로 회원을 등록하는 기능
- 다음 코드를 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 = "http://fascination-euna.members/new")
public String createFrom(){
return "members/createMemberForm";
}
// 여기서부터 추가
@PostMapping(value = "http://fascination-euna.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로 리디렉션됩니다.


- 지정된 텍스트 상자에 스프링 이름을 지정하고 등록 버튼을 클릭하면 다시 메인 페이지로 리디렉션됩니다.
- 이때 MemberController.java의 create 메소드에 다음 코드를 추가하여 멤버가 저장되었는지 확인합니다.
@PostMapping(value = "http://fascination-euna.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 내부에서 (“http://fascination-euna.members/new”)에 매핑되는 createForm 메소드가 호출됩니다.
- createForm은 viewResolver에 의해 선택되고 Thymeleaf 템플릿 엔진은 반환 코드에 의해 반환된 members/createMemberForm(templates/members/createMemberForm.html)을 렌더링하여 화면에 표시합니다.



- 페이지에 이름을 Spring으로 입력하고 Register 버튼을 클릭하면, POST 방식입력한 이름은
- createMemberForm.html을 확인하면 값을 입력하는 양식 태그 내부의 입력 태그에 name=”name”이 표시됩니다.
- “이름” 부분은 서버에 전달할 때 키 역할을 합니다.
- 즉, 컨트롤러 패키지 아래의 MemberForm에 선언된 변수 이름에 매핑되므로 입력한 값이 name에 전달됩니다.



- 등록 버튼을 클릭하면,



GET 방식은 주로 데이터 검색에 사용되고 POST 방식은 데이터 전송(등록)에 사용됩니다.
# 회원을 위한 웹 기능 – 검색
1. 멤버 컨트롤러의 쿼리 기능
- 다음 코드를 java/hello/hellospring/controller/MemberController.java에 추가합니다.
- 멤버 목록은 model.addAttribute를 통해 HTML에서 사용되는 Thymeleaf 엔진에서 사용할 수 있습니다.
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/memberList.html입니다.
- memberList.html은 Thymeleaf 템플릿 엔진 구문인 th:each를 사용하고 MemberController의 list 메서드에서 모델에 전달된 멤버를 반복하고 멤버에 저장된 객체에 대한 정보를 검색하여 테이블로 푸시합니다.
- thymeleaf에서 ${}로 표시된 내용을 통해 모델에 저장된 값을 검색할 수 있습니다.
- list 메소드는 memberservice를 통해 모든 멤버의 리스트를 멤버로 저장하며, model.addAttribute를 통해 템플릿 엔진(=thymeleaf)에서 멤버를 사용할 수 있다.
- 그냥 모델은 요소 및 값으로 AttributeName이 있는 모든 요소의 목록을 포함하는 데이터를 저장합니다.오전
- 이때, 각 구성원의 ID와 이름은 비공개로 정의되어 있으므로 속성 메서드(getter/sette를 통해 액세스)에서 데이터를 검색합니다.
- 즉, 페이지에 접근할 때 Spring은 /member와 연관된 컨트롤러(=MemberController)를 찾아 연관된 메서드(=list)를 실행합니다.



- 실제 렌더링된 페이지의 소스 코드를 살펴보면 HTML로 테이블에 두 개의 행이 생성된 것을 확인할 수 있습니다.


현재 메모리에 데이터를 저장하는 방식을 사용하고 있기 때문에 서버를 종료했다가 다시 실행하면 저장된 데이터가 모두 사라집니다.
실제로는 이런 일이 발생하지 않아야 하므로 데이터베이스를 사용합니다.