본문 바로가기
공부 및 활동/스프링 강의 정리

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

by KChang 2021. 9. 26.

1. 회원 웹 기능 - 홈 화면 추가

기존에는 localhost:8080으로 홈 화면 접속 시 static의 index.html을 띄웠지만, 이번에는 홈 화면을 띄우는 컨트롤러를 만들어 직접 작성한 홈 화면을 띄워본다.

 

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

}

@Controller를 사용해 HomeController를 스프링 컨테이너에 등록하고 @GetMapping을 사용하여 "/"와 같은 url을 입력시 (홈 화면으로 들어올 시) 다음의 메서드를 호출한다. (home())

해당 메서드는 templates 폴더에서 "home.html"을 찾아 화면에 띄워준다.

 

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>

위와 같이 파일 생성 후 프로젝트를 실행시키고 url에 localhost:8080을 입력하여 홈 화면으로 들어가면 다음과 같은 홈 화면을 볼 수 있다.

홈 화면

홈 화면

  • 회원 가입 링크를 누르면 "/members/new"로 이동
  • 회원 목록 버튼을 누르면 "/members"로 이동

(이동하는 화면, 기능은 '2. 웹 기능 - 등록'에서 구현한다.)

 

2. 스프링 웹 개발 기초에서 살펴본 것처럼 컨트롤러는 정적 컨텐츠(/static/.html)보다 우선순위가 높다. 따라서, 클라이언트에서 요청이 오면 먼저 스프링 컨테이너 안의 관련 컨트롤러를 먼저 찾고(현 프로젝트에서는 HomeController), 컨트롤러가 없을 때는 static 폴더 안에서 관련 파일을 찾는다. (현 프로젝트에서는 index.html)

현재 "/"(홈 화면)에 매핑이 되어있기 때문에(@GetMapping("/")) home.html로 이동, 컨트롤러가 없을 때의 기존의 홈 화면이었던 index.html은 무시된다.

static

 

 

2. 회원 웹 기능 - 등록

구현한 홈 화면에서 회원 가입 버튼을 누르면 "members/new"로 이동한다.

이 화면에서 회원 가입 기능을 수행하며, 이를 구현하기 위해 기존의 회원 컨트롤러(MemberController)에 다음과 같은 Get방식(url로 화면 지정)의 Mapping을 만들어준다.

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

위 메서드는 url에서 "/member/new"와 같은 요청을 받으면 "members/createMemberForm" 화면으로 이동한다.

 

templates 폴더에 members 폴더 (회원과 관련된 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>

위와 같은 코드를 작성하고 프로젝트를 실행하면 홈 화면에서 회원가입 버튼을 눌렀을 때 @GetMapping을 통해 "/members/new"로 이동, 리턴된 "/members/createMemberForm" 화면(html)을 볼 수 있다.

회원가입2

위 html 파일에서 <form> 태그는 값을 입력받을 수 있는 html 태그이다.

(form은) input으로 이름(name)을 입력 받고 등록 버튼을 누르면 post 방식으로 action url(members/new)로 이동한다.

이때 <input> 태그 안의 name = "name" 중 "name"은 입력이 서버로 들어올 때의 key 값으로, 이 입력 데이터를 전달받을 Form 객체를 만든다.

 

 

controller 폴더 아래 MemberForm 자바 파일을 생성하고 MemberForm 클래스를 작성한다.

controller/MemberForm

package hello.hellospring.controller;

public class MemberForm {
    private String name;

    public String getName() {
        return name;
    }

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

스프링은 createMemberForm.html의 "name"을 보고 MemberForm 클래스의 setName()을 호출해 멤버변수 name에 위에서 입력은 받은 데이터를 넣는다.

 

post방식의 "members/new"요청을 받아 입력받은 데이터로 실제 등록하는 기능을 구현하기 위해 회원 컨트롤러에 @PostMapping을 사용한 메소드를 만든다.

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

        System.out.println("member = " + member.getName());

        memberService.join(member);

        return "redirect:/";
    }

이전에 @GetMapping으로 요청받은 주소 "members/new"와 동일하지만, 위 코드는 @PostMapping으로 처리하므로 이전과 다르게 Mapping이 가능하다.

@GetMapping : 저장된 데이터를 조회할 때 사용

@PostMapping : 데이터를 form에 넣어 전달(등록)할 때 사용

 

 

실행

 

spring

등록 버튼을 누르면, 매개변수로 받은 MemberForm 객체 name(form)에 입력한 "spring" key가 name으로 저장되어 전달된다.

멤버 객체를 생성하고, form.getName()으로 form객체에서 입력값(name)을 꺼내 회원 객체의 setName() 메소드로 회원의 이름을 설정한다.

회원 서비스의 join() 메소드를 사용해 회원가입을 진행 후 "redirect:/"을 리턴하여 메소드를 마치면 회원가입 후 홈 화면으로 돌아간다.

실행 결과, 회원 가입이 정상적으로 완료되면, 회원의 이름이 다음과 같이 출력된다.

 

System.out.println("member = " + member.getName());

결과

 

 

 

3. 회원 웹 기능 - 조회

홈 화면

회원 목록 버튼을 눌렀을 때 현재 가입된 모든 회원을 조회할 수 있는 기능을 구현한다.

회원 목록 버튼을 눌렀을 때의 요청 "/members"을 @GetMapping 사용해 메소드를 구현한다.

 

controller/MemberController

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

home.html에서 요청 받은 "/members"를 list() 함수와 매핑한다.

list() 함수 : 회원 서비스에서 등록된 모든 회원을 리스트로 전달받아 이를 화면으로 보여주는 메소드

 

회원 서비스에서 findMembers() 함수를 사용해 등록된 모든 회원들을 리스트 형태인 members로 받고, 모델에 이를 key "members"로 담아 "members/memberList"를 리턴하면서 모델을 넘겨준다.

(위 동작은 2. 스프링 웹 개발 기초에서 설명하였다.)

 

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>

이제 Thymeleaf 템플릿 엔진이 동작한다.

모델을 넘겨받은 Thymeleaf 템플릿 엔진은 렌더링 후 변환된 html을 웹 브라우저에 띄운다.

 

'each'는 java의 for each와 비슷한 문법으로 루프를 돌며 모델로 넘겨받은 "members"라는 객체 리스트에서 객체를 하나씩 꺼내 member에 담고, 각 member의 id(.id)와 name(.name)을 출력한다.

이때 각 멤버 변수의 접근은 자바 프로퍼티 방식으로 id, name이 private이므로 property의 getter로 접근하여 값을 가져온다.

 

이제 확인하기 위해 프로젝트를 실행한다.

홈 화면 : 회원 가입, 회원 목록

1) 회원 가입 : spring1, spring2 회원을 등록한다.

2) 회원 목록 : 가입된 회원 전체 목록을 확인, id와 name을 확인할 수 있다.

 

결과2

데이터를 메모리 레파지토리에 저장하였기 때문에 서버를 close했다가 open하면 이 전에 저장된 데이터가 전부 지워진다.

실무에서는 이러한 데이터들을 파일 또는 Database에 저장해야한다.

 

 


강의

참고자료

댓글