스프링 입문 - Ch 5. 회원 관리 예제 - 웹 MVC 개발

seren-dev·2022년 3월 29일
0

스프링 입문

목록 보기
8/11

멤버 컨트롤러를 통해서 회원을 등록하고 조회

회원 웹 기능 - 홈 화면 추가

Controller 패키지 내에 HomeController 클래스 파일 추가

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

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>

먼저 스프링 컨테이너 안에서 관련 컨트롤러를 찾고, 없으면 static 파일을 찾기 때문에, index.html파일이 아닌 home.html 파일을 반환


회원 웹 기능 - 등록

회원 등록 폼 컨트롤러

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

회원 등록 폼 HTML
resources/templates/members/createMemberForm.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<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>

회원 등록 화면에서 데이터를 전달 받을 폼 객체 MemberForm
컨트롤러 폴더 내에서 MemberForm 클래스 생성

MemberForm의 목적은 화면에서 넘어온 Form 데이터를 받기 위한 목적입니다.
따라서 컨트롤러에서만 사용하는 것이 좋습니다.

도메인 패키지는 가급적 HTML Form이나 UI에서 직접 넘어오는 데이터를 모르도록 설계를 해야 좋습니다.
이렇게 분리해두면 향후 UI나 넘어오는 정보가 변경되어도 해당 도메인을 변경하지 않아도 됩니다.
(물론 도메인을 변경해야 할 만큼 큰 변화가 있으면 모두 변경이 필요합니다.)

MemberFormnamecreateMemberForm.html에서 input 태그의 name="name" 의 ""안에 있는 name과 매칭이 되면서 값이 들어옴

참고: input 태그의 name 속성
https://yangbari.tistory.com/28
name속성값: 서버로 전달되는 이름(사용자 임의 지정)
프로퍼티 바인딩: input태그의 name="name" 여기서 "name"은 MemberForm클래스의 String name 이 변수와 항상 일치 해야함

스프링 MVC는 HTTP 파라미터로 넘어오는 모든 이름들을 인식해서 (name, age 등등)
MemberForm 객체(직접 만든 아무 객체든 상관 없음)에 동일한 프로퍼티 이름이 있으면 찾아서 넣어준다.
이는 스프링 MVC가 제공하는 기본 기능이다.

MemberForm 클래스 생성 이유
사실 컨트롤러에 MemberForm 대신에 Member를 그대로 받아도 기술적인 문제는 없다. 다만 지금은 예제이지만, 실무에서는 컨트롤러에 넘어오는 정보가 Member가 필요한 데이터 이상으로 많은 데이터들이 들어온다. 예를 들어서 회원 정보 뿐만 아니라 약관 정보도 들어오고, 화면을 처리하기 위한 추가 정보들도 들어온다. 또는 Member에 필요한 정보들이 화면이 아니라 데이터베이스에 더 있을 수도 있다. 더 여러가지가 있지만, 주로 이런 이유 때문에 MemberForm과 Member를 분리하는 것이 좋다.

package hello.hellospring.controller;

public class MemberForm {
    private String name;

    public String getName() {
        return name;
    }

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

멤버 컨트롤러

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:/";
    }
}
  • 회원 가입을 들어가면 /members/new 페이지로 감
  • Get 방식 -> viewResolver를 통해 createMemberForm.html이 선택되고 렌더링
  • form 태그는 값을 입력할 수 있는 태그
    <form action="/members/new" method="post">
    <input type="text" id="name" name="name" placeholder="이름을입력하세요">
    placeholder는 아무 것도 없을 때 적히는 것
  • "spring"으로 적어주고 등록 버튼을 누르면 action URL로 post 방식으로 넘어옴
  • @PostMapping데이터를 폼에 넣어서 전달할 때
    @GetMapping조회할 때 씀
  • create 메소드 호출
    MemberFormname에 spring 값이 들어옴
    스프링이 setName을 통해 값을 넣어주는 것
  • redirect:/ 홈 화면으로 돌아감

회원 웹 기능 - 조회

멤버 컨트롤러

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

회원 리스트 HTML 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 등록하면 다음과 같이 바뀜


<!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>
  • 모델 안의 members를 읽음
  • th:each로 루프를 돌면서 로직 실행
  • getId, getName에 접근해서 값을 가져옴

메모리라서 서버를 내렸다가 다시 키면 회원 데이터가 지워짐
-> 데이터를 파일이나 DB에 저장해야 함

0개의 댓글