▣ LAB · AUTH

회원가입 폼 — name 속성과 VO 필드 매칭

JSP 폼이 서버 객체로 자동 바인딩되는 원리

📍 지금 어디를 만지고 있나요?
브라우저
<form>
Controller
signup(Member m)
Service
Mapper
DB

사전 준비

이번 실습의 목표

<input name="..."> 의 name 이 VO 필드명과 같을 때 — Spring 이 어떻게 데이터를 자동으로 객체에 채워주는지를 손으로 확인합니다. 마지막 단계에서는 일부러 name 을 어긋나게 만들어 「약속이 깨지면 어떻게 되는지」 도 직접 봅니다.

1
Member VO 작성 — 그릇 만들기

com.smhrd.domain.Member 클래스를 만듭니다. 폼에서 받을 칸과 같은 이름의 필드만 둡니다.

package com.smhrd.domain;

import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

@Data @AllArgsConstructor @NoArgsConstructor
public class Member {
    private String id;
    private String pwd;
    private String nick;
}
CHECKPOINT
  • Lombok 이 적용되어 있는지 — @Data 가 빨간 줄 안 뜨는지 확인
  • 필드명이 정확히 id, pwd, nick 인가? (대소문자 주의)
2
회원가입 폼 JSP 작성

src/main/webapp/WEB-INF/views/signup.jsp (혹은 프로젝트 규칙에 맞는 위치) 를 만듭니다. 모든 입력 칸의 name 을 VO 필드명과 같게 둡니다.

<%@ page contentType="text/html;charset=UTF-8" %>
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title>회원가입</title></head>
<body>
  <h1>회원가입</h1>
  <form action="/signup" method="post">
    <input name="id"   placeholder="아이디"><br>
    <input name="pwd"  type="password" placeholder="비밀번호"><br>
    <input name="nick" placeholder="닉네임 (선택)"><br>
    <button>가입하기</button>
  </form>
</body></html>
CHECKPOINT
  • 브라우저에서 폼 페이지가 열리는가?
  • F12 → Elements 에서 모든 input 에 name 속성이 살아있는지 확인
  • F12 → Network 탭을 켜둔다 (다음 Step 에서 사용)
3
Controller 작성 — VO 한 줄로 받기

com.smhrd.controller.SignupController 를 만듭니다. 매개변수에 Member m 만 두면 끝납니다.

package com.smhrd.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import com.smhrd.domain.Member;

@Controller
public class SignupController {

    // 폼 페이지 보여주기
    @GetMapping("/signup")
    public String form() {
        return "signup";   // /WEB-INF/views/signup.jsp
    }

    // 폼 데이터 받기
    @PostMapping("/signup")
    public String signup(Member m) {
        System.out.println("받은 회원: " + m);
        return "redirect:/signup";   // 일단 다시 폼으로
    }
}
CHECKPOINT
  • 컴파일 오류가 없는가?
  • Tomcat 재시작 후 http://localhost:8080/signup 에서 폼이 보이는가?
4
실행 — 자동 바인딩 직접 확인

폼에 값을 넣고 「가입하기」 를 눌러봅니다.

id   : hong
pwd  : mypw1234
nick : 홍길동

Eclipse 콘솔에 다음과 같은 줄이 떠야 합니다:

받은 회원: Member(id=hong, pwd=mypw1234, nick=홍길동)
CHECKPOINT — Eclipse 콘솔 + F12 Network
  • Eclipse 콘솔에 위와 같이 세 필드 모두 값이 찍히는가?
  • F12 → Network → /signup 요청 → Payload 에 id=hong&pwd=mypw1234&nick=... 가 보이는가?
  • 「내가 setter 를 부르지 않았는데 채워졌다」 — Spring 이 한 일
5
일부러 깨뜨리기 — name 어긋나게

폼 JSP 에서 첫 번째 input 의 name 만 바꿔봅니다.

<!-- 변경 전 -->
<input name="id" placeholder="아이디">

<!-- 변경 후 -->
<input name="userId" placeholder="아이디">

저장 후 다시 폼을 작성해 가입하기 — 콘솔 출력은:

받은 회원: Member(id=null, pwd=mypw1234, nick=홍길동)
                    ↑
              아이디만 null 로 들어옴
CHECKPOINT — 콘솔 + F12 Network
  • F12 → Network 의 Payload 에는 userId=hong 으로 잘 보내졌는가? (브라우저는 잘못 없음)
  • 그런데 콘솔에는 id=null — VO 에 userId 필드가 없으니 setter 가 호출되지 않은 것
  • 「약속이 깨지면 그 칸만 사라진다」 — 이게 핵심 가르침
  • 실습이 끝나면 폼을 name="id" 로 되돌려 두기
6
비교 — getParameter 로 받았다면?

같은 일을 옛날 방식으로 쓰면 다음과 같습니다 (참고만 — 실제 코드는 그대로 두세요).

@PostMapping("/signup")
public String signup(HttpServletRequest req) {
    String id   = req.getParameter("id");
    String pwd  = req.getParameter("pwd");
    String nick = req.getParameter("nick");
    Member m = new Member();
    m.setId(id); m.setPwd(pwd); m.setNick(nick);
    System.out.println("받은 회원: " + m);
    return "redirect:/signup";
}

Step 3 의 signup(Member m) 한 줄과 비교해보면 — 줄 수가 차이나는 게 아니라, 「데이터 꺼내기」 라는 관심사가 사라진다 는 게 핵심입니다.

CHECKPOINT
  • 「칸이 6 개, 10 개로 늘면 — 어느 쪽이 더 손이 가나?」 자기 말로 정리
  • 다음 차시(★ v2) 에서 이 폼이 그대로 DB 에 INSERT 되는 흐름을 만난다

실습 완료 체크리스트

Member VO 의 필드명을 폼의 name 과 같게 맞췄다
Controller 의 매개변수에 Member m 한 줄만 둬도 자동으로 채워지는 것을 봤다
콘솔에 세 필드가 모두 채워져 출력되는 것을 확인했다
일부러 name 을 어긋나게 해 그 필드만 null 이 되는 것을 봤다
같은 이름 약속이 「폼 ↔ VO」 를 잇는다는 것을 자기 말로 설명할 수 있다