▣ PART · AUTH

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

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

학습 목표

  • 회원가입 폼을 직접 만들고 서버에 POST 한다
  • <input name="..."> 가 VO 의 어떤 필드에 들어가는지 자기 말로 설명할 수 있다
  • name 이 어긋나면 어디가 null 로 들어오는지 직접 확인한다

⚠️ 이전 버전의 불편

"폼 칸 6 개를 받으려면 6 줄을 써야 하나?"

@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);
    service.signup(m);
    return "redirect:/login";
}

getParameter 가 칸 수만큼 반복됩니다. 본질(가입 처리)은 한 줄인데 — 데이터를 꺼내는 코드가 컨트롤러를 채웁니다.

🛠️ 새 도구 — 이름만 같으면 자동 바인딩

「같은 이름」 = 데이터 약속

Spring 은 매개변수에 VO 클래스가 오면 — 폼의 name 과 VO 의 필드명을 비교해 같은 이름끼리 setter 를 호출해줍니다.

<input name="id"> ──┐ <input name="pwd"> ──┼─→ Member m (m.setId, m.setPwd, m.setNick) <input name="nick"> ──┘

이름이 약속이 되면, 컨트롤러는 signup(Member m) 한 줄로 끝납니다.

회원가입 폼 — JSP


<form action="/signup" method="post">
  <input name="id"   placeholder="아이디">
  <input name="pwd"  type="password" placeholder="비밀번호">
  <input name="nick" placeholder="닉네임 (선택)">
  <button>가입하기</button>
</form>

👉 모든 입력 칸에 name 이 있어야 서버에 도달합니다. name 이 없으면 그 칸은 전송되지 않습니다.

받을 그릇 — Member VO


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

필드명 id / pwd / nick 이 폼의 name 과 정확히 같습니다. 이름이 곧 약속입니다.

Controller — 한 줄로 받기


package com.smhrd.controller;

@Controller
public class SignupController {

    @Autowired private MemberService memberService;

    @PostMapping("/signup")
    public String signup(Member m) {     // ← 자동 바인딩
        System.out.println("받은 회원: " + m);
        memberService.signup(m);
        return "redirect:/login";
    }
}

매개변수에 VO 가 오면 Spring 이 폼 데이터를 꺼내 m.setId(...), m.setPwd(...), m.setNick(...) 를 자동 호출합니다.

흐름 — name 이 setter 로 변환

브라우저 서버 │ │ │ POST /signup │ │ id=hong │ │ pwd=mypw1234 │ ← 폼 데이터 (key=value) │ nick=홍길동 │ │ ───────────────→ │ │ │ Spring: │ │ new Member() │ │ m.setId("hong") │ │ m.setPwd("mypw1234") │ │ m.setNick("홍길동") │ │ │ │ signup(m) 호출

이름이 어긋나면? (의도적 실수)


<!-- 폼만 살짝 바꿔본다 -->
<input name="userId" placeholder="아이디">   <!-- ⚠️ name 이 다름 -->
<input name="pwd"    type="password">
<input name="nick">
결과 — 컨트롤러 콘솔

받은 회원: Member(id=null, pwd=mypw1234, nick=홍길동)
                    ↑↑↑↑
            아이디만 빠짐 — DB INSERT 시 PK null 오류

👉 userId 라는 이름은 VO 에 없으므로 setter 가 호출되지 않습니다. 「약속이 깨지면 데이터가 사라진다」.

「같은 이름」 약속이 미치는 범위

[공유 약속] 필드 = id, pwd, nick │ ┌───────────────┼───────────────┐ │ │ │ Frontend Backend DB <input private CREATE TABLE name="id"> String id; mymember(id ...)

이 차시는 「Frontend ↔ Backend」 사이의 약속만 다룹니다. DB 까지의 연결은 다음 차시들에서 누적됩니다.

🔄 Before / After

Before — getParameter 6 줄

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);
After — VO 한 줄

public String signup(Member m) {
    service.signup(m);
    ...
}

👉 「데이터 꺼내기」 코드가 사라집니다. 컨트롤러는 본질(가입 호출)에만 집중.

📊 한 그림 정리

이번 차시 흐름도

브라우저
<form>
Controller
signup(Member m)
Service
Mapper
DB

이번 차시에서 새로 생긴 칸 Controller — 폼 데이터를 VO 로 자동 바인딩하는 자리.

정리

오늘 들고 가는 것

  • <input name="..."> 의 name 이 곧 「데이터 약속」
  • VO 필드명과 같으면 — Spring 이 setter 를 자동 호출
  • 이름이 어긋나면 그 필드만 null 로 들어옴
  • 컨트롤러는 signup(Member m) 한 줄로 끝

다음: ★ v2 — 원시적인 회원가입/로그인 (이 폼이 실제로 DB 까지 가는 흐름).