💻백엔드/SPRING

[Spring Boot 입문 해보기] 웹 MVC 개발

코딩하는 맹구 2024. 6. 16. 22:37

김영한 강사님의 스프링 부트 강의에 더불어 따로 공부한 내용도 추가한 글입니다.

 

✅회원 웹 첫 페이지

 

이제 홈 화면과 거기에 들어가는 기능을 추가해줘보자.

우선 컨트롤러에 HomeController를 만들어준다

//homeController.java

@Controller
public class HomeController {
    @GetMapping("/") //첫번째 도멘인 처음 화면을 맾
    public String home(){
        return "home";
    }

}

 

 

그리고 보이는 화면을 만들기위해 html을 만들어준다.

 

<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
<!--<head>-->
<!--    <meta charset="UTF-8">-->
<!--    <meta name="viewport"-->
<!--          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">-->
<!--    <meta http-equiv="X-UA-Compatible" content="ie=edge">-->
<!--    <title>스프링 테스트</title>-->
<!--</head>-->
<body>
    <div class="container">
        <div>
            <h1>Hello Spring</h1>
            <p>회원 기능</p>
            <p>
                <a href="/member/new">회원 가입</a>
                <a href="/members">회원 목록</a>
            </p>
        </div>
    </div>
</body>
</html>

 

 

실행을 하고 브라우저에 띄워보면 이렇게 잘 뜨는 것을 확인할 수 있다.

 

근데, 우리가 저번에 만들어둔 static의 index.html의 파일이 존재한다.

이 파일 또한 처음 들어갔을 때 화면에 뜨게하려고 만든건데 지금 보면 home.html이 먼저 뜨는 것을 볼 수 있다

 

(overwrite) 덮인 것 같은데,,

왜일까?

 

우선 순위가 있다고 한다.

 일단 실행하고 나서 요청이 가면 스프링컨테이너부터 뒤지게된다.

거기에 뭐가 없으면! static 파일로 가서 찾게 되어 있음

 

그래서 지금 상황은 요청이 오면 localhost:8080HomeController 부터 분석한다.

 

우리는 첫 페이지와 매핑해둔게 있으니 당연히 그 home으로 찾아 들어간다.

그렇게 호출이 되고 static 폴더에 있는 index.html나오지 않는 채로 끝나게 되는 것이다.

 

 

✅회원 웹기능 : 등록

✔ 회원 등록 폼 개발

등록을 위한 컨트롤러를 또 만들어주자.

 

등록 컨트롤러는 members에서 수행하기로 home.html에서 url을 잡아줬으므로

member 컨트롤러에 등록 껍데기? 가 되는, 매핑해주는 코드만 추가해준다.

 

...
@GetMapping("/members/new")
    public String createForm(){
        return "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>
    </body>
</html>

 

 

실행시켜서 확인해보면 이렇게 url에 맞게 잘 뜨는 것을 확인할 수 있다.

 

 

 

이제 껍데기는 만들어줬으니 실제로 이름을 입력하고 등록을 눌렀을 때 그 이름이 서버로 전송될 수 있도록 하는 등록 폼 컨트롤러를 만들어보자.

 

컨트롤러 폴더에 MemberForm을 하나 만들어주자.

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

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

 

이렇게 getter setter 까지 만들어주면 여기서의 name이 등록 폼 화면 html에서 적어둔 name이 매칭이 되면서 값이 들어오도록 하는 것이다.

 

그럼 이 memberForm이 잘 작동하기 위해서 MemberController에서 작업을 쳐주자.

어디에도 명시를 안 해주면 당연히 작동이 안될테니깐ㅎㅎ

 

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

        memberService.join(member);

        return "redirect:/";
    }

 

이렇게 추가해주고 돌려보면 내가 이름을 입력하고 등록 버튼을 누르면 리다이렉트 되면서 홈화면으로 처리 되는 것을 볼 수 있다.

 

 

다시 흐름을 살펴 보자면,,,,,,,

등록 html에서 등록 버튼을 누르면  <form action="/members/new" method="post">  이 부분이 작동하게 된다. 즉, action이라는 것은 내가 input으로 이름을 입력하게 됐을 때 /members/new POST HTTP 메서드 방식으로 전달해준다는 뜻.

 

그렇게 우리는 컨트롤러에서 PostMapping을  해주었고 그 안에서 받은 form 데이터가 선언된 Member객체에서 name으로 들어가게 되는 것이고 그렇게 세팅된 이름은 memberService join 되게 되면서 save가 되고 리다이렉트를 통해서 홈화면으로 다시 넘어오게 되는 것이다.

 

그래서 보면, url은 같지만 GET이냐 POST냐에 따라, HTTP 메서드에 따라
데이터를 전달하고 전달 받고가 달라질 수 있습니다.


 

✅회원 웹기능 : 조회

✔ 회원 목록 조회 화면

등록이 가능하게 했으니 등록한 사람들의 이름을 띄우게 해보자.

 

우선 당연히 데이터를 받아서, 보여주는 것이니 GET 매핑을 활용한다.

MemberController에 코드를 추가해주면.,,

 

@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>
</body>
</html>

 

이렇게 만들어주고 돌려서 직접 이름을 여러개 등록한 후에 목록을 조회해보면

 

 

잘 뜨는 것을 확인 할 수 있다

 

우선은 <tr th:each="member:${members}"> 여기서 ${members} 이게 모델이었었는데

 

컨트롤러 코드상에서 model.addAttribute("members", members); 여기서 mebers라는 키에다가 우리가 선언해준 List인 members 리스트를 그대로 넣어주게 했다.

 

그렇게 넣어진 members라는 데이터 모델이 th:each="member:${members}" 이 템플릿 언어로 foreach 처럼 하나씩 반복문처럼 돌면서 리스트 안에 있는 값들이 각각 호출되게 되는 것!

 

호출되면 member 변수에 들어가게 되고 그때,

<td th:text="${member.id}"></td>,<td th:text="${member.name}"></td> 여기서 text로 출력되도록 코드가 짜여진 것입니다.

근데!!! 이렇게 하면 잘 나오긴 하지만 서버를 중단 시키고 다시 열어서 목록을 조회해보면 당연히 아까 등록했던 데이터는 다 사라지게 된다. 로컬 메모리를 사용했기 때문이다.
그래서. 데이터베이스나 따로 저장해둘 파일이 필요한 것이다.

 

 


 

📄 출처