danDevlog

[Spring Boot] 회원 관리 예제 - 회원 웹 기능(홈 화면, 등록, 조회 기능) 본문

Spring 입문

[Spring Boot] 회원 관리 예제 - 회원 웹 기능(홈 화면, 등록, 조회 기능)

단데기이 2022. 3. 26. 19:39
728x90

구현한 기능들을 웹 브라우저에서 제대로 잘 작동하는지 화면을 만들어준다.

 

-홈 화면-

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";
    }
}

스프링 빈에 등록될 수 있게 @Controller 어노테이션을 달아주고, @GetMapping을 통해 주소와 매핑한다.

리턴으로 home이라는 이름의 뷰를 리턴하므로, 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>

a태그로 만든 주소중 하나는 회원가입창, 또 다른 하나는 회원 목록 창이다.

HelloSpringApplication을 실행하고 주소로 들어가보면 위와 같은 화면이 나온다.

아직 회원 가입창과 회원 목록창은 만들지 않았으므로, white label 문구가 나온다.

 

* index.html(welcome page) 보다 HomeController가 우선순위가 높기 때문에 HomeController가 먼저 작동한다.


-회원 등록 폼 컨트롤러-

회원 가입을 해보기 위해서 회원 가입 창을 만들어준다. 그 전에 MemberController에 가입창주소를 매핑시켜준다.

@GetMapping("/members/new")
    public String createForm() {
        return "members/createMemberForm";
    }

templates/members/ 경로로 새로 createMemberForm을 생성해준다.

<!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태그로 이름을 입력받는다. /members/new로 데이터를 보낼것이기 때문에 action="/members/new이고,

입력을 받아오기 때문에 "post" 이다.

하지만 이름을 입력하고 등록을 눌러도 에러가 발생한다.

이름을 받아와 등록버튼을 누르면 어떻게 할지에 대한 Controller를 작성해주지 않았기 때문이다.

 

Controller패키지에 form태그에서 이름을 받아 저장할 MemberForm 클래스를 작성한다.

public class MemberForm {
    private String name;
    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

그리고 MemberController에 다음과 같이 작성한다.

@PostMapping("members/new")
    public String create(MemberForm form) {
        Member member = new Member();
        member.setName(form.getName());

        memberService.join(member);

        return "redirect:/";
    }

잘 보면 @GetMapping이 아니라 @PostMapping 이다. 이는 폼태그에서 name을 받아오기 때문이다.

폼태그에서 바당온 name을 저장한 객체인 MemberForm을 매개변수로 받아오고, 새 멤버 인스턴스를 생성한다.

그리고 새 멤버 인스턴스의 setName과 form.getName()을 통해 이름을 저장한다.

 

member.setName(form.getName()); 에서 setName으로 이름을 지정하기 전인데 어떻게 getName이 나오는가에 대해서,

스프링 컨트롤러는 해당 컨트롤러 메서드가 호출되기 직전에 form.setName()이 자동으로 실행되어 폼태그로 받은 

name을 저장해준다. (스프링 MVC의 기능)

 

마지막 return "redirect:/" 는 홈 화면으로 이동하게해준다.


-회원 목록 조회-

MemberController에 마찬가지로 메소드를 작성해준다.

@GetMapping("/members")
    public String list (Model model) {
        List<Member> members = memberService.findMembers();
        model.addAttribute("members",members);
        return "members/memberList";
    }

Model 객체는 Controller에서 생성된 데이터를 담아서 View로 전달할 때 사용하는 객체이다.

addAttribute("키", "값") 메서드를 사용하여 전달할 데이터를 세팅한다.

직접 model을 생성할 필요 없이 파라미터로 선언만 해주면 스프링이 알아서 만들어준다.

 

회원 목록 창을 만들어보자 (경로 : templates/members/memberList)

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div class="container">
  <div>
    <table>
      <thead>
      <tr>
        <th>#</th> //table heading
        <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>
  • ${} 는 model안에 있는 값은 꺼낸다는 뜻
  • th:each는 thymeleaf 문법으로, list로된 members를 each로 루프를 돈다. (foreach문법이랑 유사)
  • th:text는 출력 기능
  • member.id와 member.name을 호출하면 자동으로 member.get~~ 메서드가 호출되어 값을 가져온다(자바 프로퍼티 방식 접근)

 

Comments