아주 단순하게 회원을 등록하고, 회원을 조회할 수 있는 홈 화면을 만들어보자
controller 패키지에서 HomeController 클래스 생성
package hello.hellospring.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HomeController {
@GetMapping("/") // /는 localhost처음 들어왔을 때 밑에 코드가 호출 돼!
public String home(){
return "home";
}
}
@Controller 어노테이션 붙여줘 그리고 @GetMapping을 통해 "/"연결해
/(슬래시)는 도메인의 첫 번째 주소를 말한다. 즉 localhost:8080/에 접속했을 때 이 메서드가 호출된다.
localhost8080/ 요청을 받으면 return "home"을 하도록 코드 작성했으니 home.html을 만들어줘야해. resources/templates에 만들어줘
이전에 공부했던 것처럼 String home을 반환하면 templates 패키지에서 home.html을 찾아갈거야 --> localhost:8080/ 메인화면에 접속했을 때 home.html로 연결되게끔 설정완료!
먼저 스프링 컨테이너 안에 있는 컨트롤러가 있는지 찾고 없으면 static파일을 찾도록 되어 있어! 그렇기에 지금처럼 localhost:8080의 요청이 오면 먼저 Controller에서 찾아봐. 홈 화면에 Mapping된 것이 있다면 그 컨트롤러를 호출하고 끝나! (정적 리소스에 있는 index는 무시돼)
<!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>
다음과 같은 화면이 출력된다. 기능으로는 회원 가입, 회원 목록이 있는데.. 하지만 여기서 버튼을 눌러도 페이지 에러가 나오고 페이지가 제대로 나오지 않을 것이다.
아직 페이지 연결을 하지 않았기 때문이다.
<a href="/members/new">회원 가입</a>
<a href="/members">회원 목록</a>
이제 /members/new를 요청하면 "회원 가입" 기능이, /members를 요청하면 "회원 목록" 기능이 실행되도록 코드 작성해야 한다.
즉 "회원 가입"버튼을 눌렀을 때, 회원 가입 폼(Form)이 나오고 아이디를 적으면 회원 가입이 되는 것. form객체는 <form>태그를 이용하여 각종 입력양식을 입력받아 서버로 전달하는 기능을 담당해
MemberController에서 GetMapping을 통해 url을 연결하는 메서드 createForm을 작성하자.
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;
@Controller
public class MemberController {
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService){
this.memberService = memberService;
}
@GetMapping("/members/new")
public String createForm(){
return "members/createMemberForm";
}
@PostMapping("/members/new")
public String create(MemberForm form){
Member member = new Member();
member.setName(form.getName());
memberService.join(member);
return "redirect:/"; //홈 화면으로 보내.
}
}
이 메서드에서는 별 다른 기능은 하지 않고, 바로 createMemberForm.html로 연결만 한다.
여기서 중요한게 볼 건 return 값이 members/createMemberForm인 것.
기본적으로 반환된 String의 이름을 가지고 있는 html파일을 template 패키지에서 찾는데 이런 식으로 작성하면 경로로 인식한다.
즉 templates-members 패키지에 있는 createMemberForm.html을 찾게 되는 것이다.
이제 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>
이 페이지에서는 "회원 가입"시 필요한 정보를 적고, 등록 버튼을 눌러 회원 가입을 한다.
아직 /members/new를 post방식으로 받는 메서드를 작성하지 않았기 때문에, 등록을 눌러도 페이지 에러가 뜰 것이다.
웹 등록 화면에서 데이터를 전달 받을 폼 객체
createMemberForm.html에서 key는 name, value는 입력받은 값(String)으로 묶어서 전달한다. 이러한 값을 저장할 수 있는 클래스 하나 생성해야해!
java/controller에 MemberFrom 객체를 생성하자.
이 클래스에서는 받은 값을 변수에 저장한다. 회원 가입 시 필요한 정보가 문자열이므로 String변수 name을 선언하고 Getter Setter도 추가
createMemberForm.html에서의 name과 MemberForm의 name변수가 서로 매칭이 되면서 값을 받아올 것.
이제 웹에서 입력 받은 데이터를 통해서 회원 가입하는 코드 작성
createMemberForm.html에서 /members/new를 post방식으로 전달하는 것을 확인했잖아. 그 메서드를 작성해줘야지
전달받은 값을 MemberController에서 @PostMapping을 통해 연결
즉 MemberController에서 @PostMapping 어노테이션을 통해 입력 받은 데이터를 실제로 등록
@PostMapping("/members/new")
public String create(MemberForm form){
Member member = new Member();
member.setName(form.getName());
memberService.join(member);
return "redirect:/"; //홈 화면으로 보내.
}
매개변수 MemberForm을 통해 createMemberForm.html에서 name의 정보 받고, Member객체를 생성한 후 setName을 통해 아이디로 설정.
이 member객체를 memberService를 통해 회원가입(join)을 진행한다.
이후 return "redirect:/";를 통해 홈 화면으로 돌아가게 한다!(이 부분은 일단 이해하고 넘어가자)
PostMapping은 보통 데이터를 Form같은 곳에 넣어서 전달할 때 사용하고, GetMapping은 조회할 때 주로 사용한다.
회원 등록 끝! 등록된 회원 목록 조회 기능 추가하자!
회원 목록 컨트롤러
홈 화면에서 "회원 목록"버튼을 눌렀을 때, 회원 목록이 뜨도록 해보자
home.html에서 "회원 목록"을 눌렀을 때 /members로 이동하게 해놨잖아
그러므로 @GetMapping 어노테이션을 통해 매핑을 해주고, 회원 조회를 하는 메서드를 작성해야해.
@GetMapping("/members")
public String list(Model model){
List<Member> members = memberService.findMembers(); //member다 가져와
model.addAttribute("members", members);
return "members/memberList";
}
Model은 HashMap 형태를 갖고 있으며, key, value값을 가지고 있다. 또한 addAttribute()와 같은 기능을 통해 모델에 원하는 속성과 그것에 대한 값을 주어 전달할 뷰에 데이터를 전달할 수 있다.
스프링에서 Controller의 메서드를 작성할 때 특별하게 Model이라는 타입을 파라미터로 지정할 수 있음. Model객체는 JSP에 컨트롤러에서 생성된 데이터를 담아서 전달하는 역할을 하는 존재이다. 이를 이용해서 JSP와 같은 뷰(View)로 전달해야 하는 데이터를 담아서 보낼 수 있다.
메서드의 파라미터에 Model 타입이 지정된 경우에는 스프링은 특별하게 Model타입의 객체를 만들어서 메서드에 주입하게 된다.
먼저 회원 목록을 출력하는 기능을 가진 함수를 만들 것이므로 /members url과 연결해야해
그러므로 @GetMapping("members")를 통해 url과 연결한다.
매개변수 Model을 받은 후 memberService의 findMembers메서드를 통해 받은 값을 List변수에 담고 매개변수로 받은 Model에 addAttribute메서드를 이용하여 회원들의 정보를 담아.
return "members/memberList"; --> templates/members패키지에서 memberList.html을 찾도록 해!
java/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>
이렇게 작성한 후 실행.
"회원 등록"버튼을 누르고 spring1과 spring2등록해보자. 이후 "회원 목록"버튼을 누르면 spring1과 spring2가 있는 것을 확인할 수 있어.
해당 웹 페이지에서 소스보기를 통해 코드를 확인해보자
<!DOCTYPE HTML>
<html>
<body>
<div class="container">
<div>
<table>
<thead>
<tr>
<th>#</th>
<th>이름</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>spring1</td>
</tr>
<tr>
<td>2</td>
<td>spring2</td>
</tr>
</tbody>
</table>
</div>
</div> <!-- /container -->
</body>
</html>
코드가 더 길어진 이유는 template engine인 thymeleaf가 작동하여 렌더링하고 있기 때문.
<tr th:each="member : ${members}">
<td th:text="${member.id}"></td>
<td th:text="${member.name}"></td>
</tr>
중요한건 위 부분이다.
${members}는 Model에 key가 members인 value를 읽어들이라는 뜻.
MemberController에서 model에 addAttribute를 통해 회원 정보를 List로 전달했기 때문에 해당 List가 전달될 것이다.
(th:each는 members에 있는 모든 요소들을 방문하게 하는 thymeleaf 문법!)
우선 첫 번째 객체를 하나 꺼내서 member에 담고 id와 name을 출력해. 이 때 이전에 설정한 Getter함수를 통해 값 받아와
이런 식으로 모든 회원을 돌면서 회원의 id와 name을 화면에 렌더링한다.
이 모든 과정을 수행하면 간단한 회원관리 웹 페이지를 만들어볼 수 있다.
현재는 메모리를 이용하는 memoryMemberRepository를 이용하고 있다. 하지만 메로리를 이용하기 때문에 re-run을 하게 될 경우 회원들의 정보가 모두 지워지게 된다. (실무에서 이렇게 했다간...) JAVA메모리 안에 저장되기 때문에 자바를 실행 중단하게 되면 모든 데이터가 사라지게 되는 것! 이렇게 하면 안되는걸 알잖아. 이제 이 회원 데이터들을 DB에 저장을 해보자!
다음시간에...
이 글은 강의 : 김영한 - "스프링 입문-코드로 배우는 스프링 부트, 웹 MVC, DB접근기술"을 듣고 정리한 내용입니다.