📡 회원관리예제 - 웹 MVC 개발
이제까지 만들어둔 코드를 바탕으로 웹 MVC를 기반으로 회원관리 예제를 만들어보도록 하자. 해야할 일은 다음과 같다.
- 회원 웹 기능 - 홈 화면 추가
- 회원 웹 기능 - 등록
- 회원 웹 기능 - 조회
1. 회원 웹 기능 - 홈 화면 추가
src/main/java/hello.hellospring/controller 아래 HomeController 파일을 하나 만들어주자.
코드는 다음과 같다.
- "/"는 localhost:8080으로 들어왔을 때의 첫 페이지를 의미한다.
- localhost:8080으로 들어왔을 때 home.html이 실행이 된다.
이를 위해 src/java/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>
- "회원 가입" 을 클릭하게 되면 "/members/new"로 이동한다.
- "회원 목록" 을 클릭하게 되면 "/members"로 이동한다.
서버를 실행시키고 localhost:8080으로 접속해보면 위와 같이 방금 만들어준 페이지가 뜬다.
원래 static아래 있는 index.html이 떴는데 왜 이렇게 바뀌게 된 것일까?
위 그림은 스프링 입문 정리 #2에서도 나오는 그림이다. 여기서 알아봤던 것처럼 URL 요청이 오면 스프링 컨테이너의 관련 컨트롤러가 있는지 먼저 찾아보고, 없는 경우 static 파일에서 찾게 된다.
우리가 HomeController에서 @GetMapping("/")
을 통해 연결해주었기 때문에 static에 있는 파일이 아닌 templates아래 home.html이 렌더링 되는 것이다.
만약 HomeController에서 @Controller
를 삭제한다면 다시 index.html이 렌더링 될 것이다.
2. 회원 웹 기능 - 등록
회원 등록 폼 개발
home.html에서 회원 가입을 클릭했을 때 회원 가입 페이지로 넘어갈 수 있도록 MemberController를 아래와 같이 수정해주자.
그리고 src/java/resources/templates 아래 members폴더를 만들어주고 그 아래 createMemberForm.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>
- form의 action은 "members/new"라고 되어있고, method는 "post"로 되어있다.
- "name"은 서버로 넘어올 때 키가 된다.
회원등록 컨트롤러 MemberForm파일을 src/main/java/hello.hellospring/controller 아래 만들어주자.
코드는 다음과 같다.
package hello.hellospring.controller;
public class MemberForm {
// createMemberForm.html 의 input 의 name이 name이기 때문에
// 스프링이 알아서 MemberForm 의 name에 값을 넣어줌
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
이후 MemberController에 위와 같은 코드를 추가해주자. 코드가 어떻게 동작하는지 설명하면 다음과 같다.
createMemberForm.html에서 form의 action은 "members/new"로, method는 "post"로 되어있다. 그래서 등록 버튼을 클릭하게 되면 "members/new"로 이동하게 되고 post방식으로 데이터를 넘겨준다. 그러면 @PostMapping()
이 된 creat()
메서드를 호출하게 되고, 받아온 form에서 getName()
을 통해 웹에 입력된 이름을 가져오고, 그것을 Member의 프로퍼티로 저장한 뒤 join()
메서드를 통해 memberService에 저장하여 관리한다.
이러한 과정이 끝나고 redirect:/ 를 통해 홈화면으로 보낼 수 있다.
URL이 같아도 Get이냐 Post냐에 따라 다르게 매핑할 수 있다.
실제 동작화면은 위와 같다. localhost:8080에서 "회원 가입"을 클릭하면 localhost:8080/members/new로 이동하게 되고 직접 이름을 입력한 뒤 등록 버튼을 클릭하면 서버 메모리(memberService)에 저장된다.
3. 회원 웹 기능 - 조회
MemberController에 위와 같은 코드를 추가해주자.
memberService의 findMembers()
메서드를 통해 현재 저장되어 있는 모든 회원 리스트를 가져올 수 있다. 그리고 model의 addAttribute()
메서드를 통해 회원 리스트를 담고 화면에 넘겨준다.
이후 members/memberList 를 반환한다.
src/java/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}"> <!--th:each 루프를 돔-->
<td th:text="${member.id}"></td>
<td th:text="${member.name}"></td>
</tr>
</tbody>
</table>
</div>
</div> <!-- /container -->
</body>
</html>
- th:each 를 통해 루프를 돔(타임리프 문법)
실제 동작화면은 위와 같고, 추가해주었던 spring1, spring2가 있는 것을 확인할 수 있다.
중요한 점은 실제 데이터 베이스가 아니라 메모리에 저장하는 구조이기 때문에 서버를 내렸다가 다시 올리게 되면 이전에 저장했던 이름들이 사라진다는 점이다.
그러니까 회원 조회 기능을 만들고 다시 서버를 올린후에 spring1, spring2를 다시 추가해줘야 한다는 말이다.