웹 MVC 개발
1. 회원 웹 기능 - 홈 화면 추가
회원을 등록하고 조회하는 페이지로 이동할 수 있는 링크가 걸린 홈 화면을 먼저 만들어보려고 한다. 이렇게 하면 슬래시는 localhost:8080으로 들어가면 바로 이 메서드가 호출된다는 것이다.
@Controller
public class HomeController {
@GetMapping("/")
public String home() {
return "home";
}
}
또 이어서 template 아래에 있는 home.html이 호출될 것이므로, 파일을 생성해주자.
<!DOCTYPE html>
<html lang="en" 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>
</body>
</html>
이렇게 한후 실행을 시키고, localhost:8080으로 접속하면 다음과 같은 화면이 뜬다.
회원 가입 링크를 누르면 http://localhost:8080/members/new 이 url로 접속되고, 회원 목록 링크를 누르면 http://localhost:8080/members 이 url로 접속된다.
그런데 원래 홈화면을 만들기 전에는 localhost:8080으로 접속을 하면 static/index.html이 화면에 뿌려졌었다. 스프링에서 요청이 오면 스프링 컨테이너에 관련 컨르롤러를 먼저 찾고, 없다면 정적 컨텐츠를 찾는다. 따라서 index.html보다 HomeController의 home메서드를 먼저 찾게 되는 것이다.
2. 회원 웹 기능 - 등록
이번에는 회원을 등록하는 화면을 만들 것이다. 먼저 MemberController에서 회원을 등록하는 화면을 띄울 메서드를 만든다.
@GetMapping("members/new")
public String createForm() {
return "members/createMemberForm";
}
리턴되는 경로로 스프링이 화면을 찾을 수 있도록 templates 폴더 밑에 members 폴더를 만들고 그 밑에 createMemberForm.html을 다음과 같이 작성한다.
<!DOCTYPE html>
<html lang="en" 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" placeholer="이름을 입력하세요.">
</div>
<button type="submit">등록</button>
</form>
</div>
</body>
</html>
이 화면에서 이름을 spring이라고 입력 후 등록 버튼을 누르면 이 name이라는 key와 spring이라는 value가 서버에 넘어가게 된다. 물론, 지금은 아무것도 없으니 오류가 난다.
일단 회원 등록이 무사히 되도록 MemberForm 클래스를 등록하고 name이라는 문자열 필드를 만든다.
package com.heejin.hellospring.controller;
public class MemberForm {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
그러고나면 MemberController에서 MemberForm 형태로 사용자의 입력 값을 받는 create 메서드를 만들고 Post 요청으로 설정되도록 @PostMapping애노테이션을 추가한다. 파라미터로 받은 form객체에서 name 필드를 꺼내어 새 멤버 객체의 name으로 초기화해주고, 이것을 MemberService 객체에 대하여 join을 호출하여 정상적으로 회원을 추가할 수 있게 한다. 모든 작업이 끝나면 홈화면으로 갈 수 있도록 리다이렉트를 리턴한다.
@PostMapping("members/new")
public String create(MemberForm form) {
Member member = new Member();
member.setName(form.getName());
memberService.join(member);
return "redirect:/";
}
원리를 설명하자면, 회원가입 링크를 홈화면에서 누르면 url에 직접 쳐서 들어가게 되면 이것을 get방식으로 설정되어 createForm으로 매핑된다. 그리고 이 메서드에서 리턴한 members/createMemberForm에 해당하는 뷰를 찾고, 이것을 렌더링되어 브라우저 위에서 뿌려진다. form 태그는 값을 입력할 수 있는 태그이다. 폼 안에서 action은 members/new라고 되어있고, method는 post로 설정되어있다. input 태그는 type은 text, name은 서버로 들어가는 정보에서 key값에 해당되는 것으로 name으로 설정되어있다. 여기서 사용자가 문자열을 입력하고 등록버튼을 누르면 action url로 post방식으로 넘어오게된다. 그러면 MemberController에서 PostMapping으로 설정되어있던 create 메서드와 매핑된다. 보통 무언가를 등록할 때는 post, 조회할때는 get 방식으로 설정한다.
MemberForm의 name이라는 필드의 값으로 사용자의 입력값이 들어가게 된다. 스프링이 MemberForm의 setter 메서드를 호출하여 name 필드에 값을 넣어주는 것이다. 따라서 우리는 create 메서드 내에서 getter를 통해 name 값을 꺼내어 Member의 name으로 초기화를 해준 것이다.
3. 회원 웹 기능 - 조회
이제는 회원 목록을 조회하는 화면을 만들 것이다. 일단 get 방식으로 mapping될 list 메서드를 MemberController에 다음과 같이 작성한다. 현재 저장소에 저장된 모든 회원의 목록을 List 형태로 memberService를 통해 리턴받아 그것을 Model 객체에 넣어준다. 그리고 매핑될 뷰의 경로를 리턴한다.
@GetMapping("/members")
public String list(Model model) {
List<Member> members = memberService.findMembers();
model.addAttribute("members", members);
return "members/memberList";
}
이렇게 했다면 templates/members 밑에 memberList.html을 만들어줘야 한다.
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<body>
<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>
</body>
</html>
템플릿 언어에서 ${members}는 모델안에있는 값을 꺼내는 것이고, th:each은 List 안에 있는 요소를 루프를 돌면서 값을 꺼낼 수있게 하는 타입리프 문법이다. 따라서 루프를 돌면서 각 요소가 되는 멤버 객체의 id와 name 값을 꺼내어 출력할 것이다. 이때도 마찬가지로 Member 클래스에 정의된 getter 메서드를 통해 값을 꺼내게 된다.
다만 저장소가 메모리 형태이기 때문에 서버를 껐다가 다시 켜면 회원 데이터는 다 사라질 것이다. 그래서 우리는 이 데이터들을 파일이나 데이터 베이스에 저장을 해야 한다. 다음 시간에는 데이터 베이스를 설치하여 데이터 액세스에 대한 과정을 배우게 될 것이다.
Comments