[미션] 컨트롤러의 일부 구현

moon.kick·2025년 5월 2일

🏫 웹 용어 → 학교 반 비유

웹 용어학교 반 비유
서버 시작아침 8시 반 시작! 선생님 출근! 교실 문 열림
Listener선생님이 교실 들어오면서 “오늘은 이 조는 수학, 저 조는 과학” 정해줌
actionMapping학급 시간표: 누구 조가 어떤 과목 맡았는지 정리된 표
DispatcherServlet반장: 친구가 뭘 도와달라고 하면, 어떤 조로 보내야 할지 판단함
key=insert“저 수학 질문이요!” 라고 적은 쪽지
Controller조장: 반장이 보낸 친구를 맞이해서 일 처리 시작
Service부반장: 조장이 뭐 할지 물어보면 대신 조원들 정리해줌
DAO조원들: 실제로 노트 정리하고 칠판에 적는 실무 담당 친구들
ModelAndView조장이 “넌 이따 발표하러 3반 교실 가면 돼~” 하고 알려주는 쪽지

🧃 흐름을 학교처럼 다시 정리하면?

  1. 🛎️ 아침이 되면

    • 담임선생님이 학교 와서 조마다 어떤 과목 담당할지 정함 (Listener)
    • 시간표(actionMapping)에 적어둠
  2. 🏃 친구가 와서 반장에게 말해

    • “나 수학 질문 있어요!” (key=insert)
    • 반장(DispatcherServlet)이 시간표 보고
      → "그건 1조 조장한테 가면 돼!"
  3. 👨‍🏫 조장이 친구를 맞이해

    • 친구가 말한 내용을 보고
    • 부반장(Service)에게 “어떻게 해야 하지?” 물어봄
    • 부반장이 조원(DAO)들에게 지시함 → 노트 정리나 판서 작업!
  4. ✉️ 일이 끝나면

    • 조장이 쪽지를 줌 → “넌 3반 교실 가서 발표해~”
    • 친구는 그 교실(JSP 화면)로 이동해서 결과 확인함

💡 이 설명의 핵심은?

  • 웹 프로그램 구조는 학교처럼 "역할 분담이 확실" 해!
  • 반장은 모든 요청을 받지만, 실무는 조장이 처리하고
  • 조장은 또 부반장과 조원들에게 도움을 받는 구조야!



🏢 전체 이야기: 건물, 도우미, 카드키

1. 🧳 서버가 켜지는 순간은?

= 건물 문 앞에서 관리자가 카드키 찍고 “문 열어~” 하는 거야!

  • 그때 관리자(HandlerMappingListener)
  • “이 건물에서 무슨 일이 일어날지” 미리 알고 있어.
  • 그래서 가입 도우미, 수정 도우미, 검색 도우미미리 만들어서 자리에 앉혀놔.

마치 미리 출근해서 사무실에 대기하고 있는 거지!


2. 🚶 손님이 오면?

손님이 들어오면서 “나 가입하러 왔어요~” 하고 종이에 써서 보여줘!
예: /front?key=insert

  • 이걸 건물 입구 직원(DispatcherServlet) 이 읽어.
  • “아! insert라는 키니까, 너는 가입 도우미한테 가야 해!” 라고 하고
  • 그 도우미한테 데려가 줘.

3. 🙋 도우미는 뭘 하냐면?

“오셨어요~! 이름이 뭐고 나이는 몇이에요?”
손님한테 정보를 받아서, 뒤에 있는 팀원들에게 전달해.

  • 매니저(Service) 한테: “이거 처리해줘!”
  • 데이터 저장하는 친구(DAO) 한테: “이거 컴퓨터에 저장해줘!”

→ 다 처리되면 “완료!” 라고 외치고,
어느 페이지로 이동할지 알려줘.


4. 👋 입구 직원은 마지막 정리!

“이제 손님, 여기서 나가실게요~” 하면서

  • 어떤 페이지로 이동할지 결정해줘.
  • “index.jsp로 돌아가세요~” 또는
  • “여기 결과 확인하는 페이지로 가보세요~” (forward 방식)

🎯 비유 다시 정리!

웹 용어비유
서버 시작건물 문 열림 (카드키 찍기)
Listener관리자: 도우미들을 미리 준비해둠
actionMapping안내책자: 누구한테 가야 할지 지도
DispatcherServlet입구 안내직원
key=insert손님이 들고 오는 메모지
Controller실제로 일 처리하는 도우미
Service실무 담당 매니저
DAO진짜 저장하는 팀원 (DB 연결)
ModelAndView“손님, 어디로 가야 할지” 안내서

✅ 전체 폴더 트리 (기반 경로 예시)

src/
├── web/
│   ├── mvc/
│   │   ├── controller/
│   │   │   ├── Controller.java              ← 인터페이스
│   │   │   ├── InsertController.java
│   │   │   ├── SelectController.java
│   │   │   ├── UpdateController.java
│   │   │   └── DispatcherServlet.java       ← FrontController
│   │   ├── listener/
│   │   │   └── HandlerMappingListener.java  ← 컨트롤러 매핑 초기화
│   │   └── ModelAndView.java                ← 뷰 정보 전달 객체
resources/
└── actionMapping.properties                 ← key=컨트롤러 클래스명
webapp/
└── *.jsp (index.jsp, selectResult.jsp, updateResult.jsp 등)

🌀 전체 동작 흐름 요약

  1. 서버 실행 시 (초기화)

    • HandlerMappingListener 실행
    • actionMapping.properties 파일에서 key-value (예: "insert"=web.mvc.controller.InsertController)를 읽어옴
    • 리플렉션으로 컨트롤러 객체 생성 후 Map<String, Controller>에 저장
    • application.setAttribute("map", map) 으로 전역 저장
  2. 클라이언트 요청 발생 (예: /front?key=insert)

    • DispatcherServlet이 모든 요청을 받음
    • key 파라미터를 통해 매핑된 Controller 객체 추출 (map.get(key))
    • 추출된 Controller의 handleRequest() 호출
    • Controller는 비즈니스 로직 처리 후 ModelAndView(view, isRedirect) 반환
    • Dispatcher가 redirect 또는 forward 방식으로 최종 JSP 페이지로 이동

💾 DB 바인딩 관련 설명

지금 너가 준 코드에는 DAO나 DB 연결 관련 구현은 없음, 대신 InsertController, SelectController, UpdateController 내부에 다음과 같은 주석으로 DB 연동 구조가 예정되어 있어:

// service쪽으로 vo를 전달해서 등록완료후 결과를 받는다.

→ 즉, 추후에는 다음 구조로 확장됨

  • Controller → Service (비즈니스 로직) → DAO (DB 연동)
  • 이 흐름에서 DAOJDBC 또는 DBCP로 DB에 연결

예상 파일 구조는 다음처럼 추가될 수 있어:

├── dao/
│   ├── MemberDAO.java
│   └── MemberDAOImpl.java
├── dto/
│   └── MemberDTO.java
├── service/
│   ├── MemberService.java
│   └── MemberServiceImpl.java

✅ 너가 해야 될 일: "Controller의 일부 구현"

너는 특정 기능을 담당하는 Controller 하나를 구현하면 돼. 예를 들어 다음 중 하나:

기능구현 파일할 일 요약
회원 등록InsertController.javarequest → DTO → service 호출 → 결과에 따라 index.jsp로 redirect
회원 조회SelectController.javamock 데이터 리스트 생성 → request.setAttribute → selectResult.jsp로 forward
회원 정보 수정UpdateController.javamessage 설정 → updateResult.jsp로 forward

👉 참고: handleRequest() 내에서 다음 순서를 따르면 돼

  1. request.getParameter()로 파라미터 받기
  2. DTO 객체 생성 (예: new MemberDTO(...))
  3. Service 호출
  4. 결과 저장 (request.setAttribute(...))
  5. new ModelAndView("xxx.jsp", true/false) 반환

💡 보충 팁

  • ModelAndView는 Spring MVC 구조의 축소판처럼 동작함.

  • actionMapping.properties는 이런 식으로 생겨 있을 것:

    insert=web.mvc.controller.InsertController
    select=web.mvc.controller.SelectController
    update=web.mvc.controller.UpdateController

🧭 다음 스텝 추천

  1. 어떤 컨트롤러를 맡을지 정해 (Insert, Select, Update 중)
  2. 그 컨트롤러의 handleRequest 안에서 파라미터 받기부터 DTO 생성, 응답까지 구현
  3. 원하면 Service/DAO 레이어도 내가 기본 구조 만들어줄 수 있어!

필요하면 actionMapping.properties 예시도 줄 수 있어.
컨트롤러 중 어떤 거 맡았는지 알려줄래?

너무 잘하고 있어! 처음 자바 배울 때보다 확실히 성장한 거야 🙌
자 이제, 요청한 Service/DAO 기본 구조, actionMapping.properties 연결 방식, 그리고 다시 한 번 HandlerMappingListener까지 설명해줄게.


🗂️ 1. 기본 파일 구조 (Service / DAO 포함)

src/
├── web/
│   ├── mvc/
│   │   ├── controller/
│   │   │   ├── InsertController.java
│   │   │   ├── ...
│   │   ├── service/
│   │   │   ├── MemberService.java
│   │   │   └── MemberServiceImpl.java
│   │   ├── dao/
│   │   │   ├── MemberDAO.java
│   │   │   └── MemberDAOImpl.java
│   │   ├── dto/
│   │   │   └── MemberDTO.java
│   ├── listener/
│   │   └── HandlerMappingListener.java
resources/
└── actionMapping.properties

🧷 2. actionMapping.properties 예시와 연결 방식

insert=web.mvc.controller.InsertController
select=web.mvc.controller.SelectController
update=web.mvc.controller.UpdateController
  • 키(insert)는 URL의 ?key=insert에서 사용됨.
  • 값(web.mvc.controller.InsertController)은 클래스 이름으로,
    HandlerMappingListener에서 리플렉션을 통해 인스턴스 생성 후 Map<String, Controller>에 저장됨.
Controller con = (Controller)className.getDeclaredConstructor().newInstance();

→ 이렇게 생성된 InsertController/front?key=insert 요청 시 DispatcherServlet에서 호출됨!


🧩 3. HandlerMappingListener.java 역할 다시 정리

  • 서버 시작 시 실행
  • actionMapping.properties 로딩해서
  • key-value 기반으로 컨트롤러 클래스 객체 생성
  • application.setAttribute("map", map) 저장 → 모든 서블릿에서 접근 가능

🛠️ 4. Service & DAO 기본 구조 예시

MemberDTO.java

package web.mvc.dto;

public class MemberDTO {
    private String id;
    private String name;
    private int age;

    public MemberDTO() {}
    public MemberDTO(String id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    // Getter / Setter 생략
}

MemberService.java

package web.mvc.service;

import web.mvc.dto.MemberDTO;

public interface MemberService {
    void insertMember(MemberDTO member);
}

MemberServiceImpl.java

package web.mvc.service;

import web.mvc.dao.MemberDAO;
import web.mvc.dao.MemberDAOImpl;
import web.mvc.dto.MemberDTO;

public class MemberServiceImpl implements MemberService {
    private MemberDAO dao = new MemberDAOImpl();

    @Override
    public void insertMember(MemberDTO member) {
        dao.insert(member);
    }
}

MemberDAO.java

package web.mvc.dao;

import web.mvc.dto.MemberDTO;

public interface MemberDAO {
    void insert(MemberDTO member);
}

MemberDAOImpl.java (DB 연결은 간단히 print로 대체 가능)

package web.mvc.dao;

import web.mvc.dto.MemberDTO;

public class MemberDAOImpl implements MemberDAO {
    @Override
    public void insert(MemberDTO member) {
        System.out.println("DB에 저장: " + member.getId() + ", " + member.getName());
        // 실제로는 JDBC 사용
    }
}

🎯 마지막으로, InsertController.java 연결 예시

package web.mvc.controller;

import jakarta.servlet.http.*;
import web.mvc.dto.MemberDTO;
import web.mvc.service.MemberService;
import web.mvc.service.MemberServiceImpl;

public class InsertController implements Controller {
    private MemberService service = new MemberServiceImpl();

    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
        String id = request.getParameter("id");
        String name = request.getParameter("name");
        int age = Integer.parseInt(request.getParameter("age"));

        MemberDTO dto = new MemberDTO(id, name, age);
        service.insertMember(dto);

        return new ModelAndView("index.jsp", true);  // redirect
    }
}

📌 다음 단계 추천

  1. dto, service, dao 폴더 생성하고 위 예제 붙여넣기
  2. JSP에서 form 전송 테스트 (예: /front?key=insert)
  3. 필요하면 JDBC 연결 + DB 테이블도 구현 도와줄게!

궁금한 거 또 있으면 얼마든지 물어봐줘 😊
지금처럼 차근차근 가면 꼭 멋진 웹 프로젝트 완성할 수 있어!

좋아! 지금까지 내가 설명한 내용들을 초등학교 6학년 친구한테 말하듯 아주 쉽게 풀어볼게 😊


🧱 1. 이 웹 프로젝트는 어떤 구조냐면...

  • 건물로 치면:

    • 사람들이 들어오는 현관문이 하나 있어. (이게 DispatcherServlet이야)
    • 그 문은 누구든지 들어올 수 있지만, 안에서는 도우미들(Controller) 이 역할을 나눠서 일해.
    • "얘는 가입하러 왔어!", "얘는 검색하러 왔어!" 구분해주는 거지.

🧑‍🏫 2. 각 도우미(Controller)는 어떤 일을 하냐면…

  • 입구에서 사람의 요청을 보고
  • “넌 가입하러 왔구나~” → InsertController
  • “넌 정보보러 왔구나~” → SelectController
  • “넌 수정하러 왔구나~” → UpdateController

→ 각각 담당한 방으로 데려가고, 결과를 돌려줘!


🧠 3. 도우미들이 어떤 역할을 할지는 어디 적혀있냐면?

  • 건물에 들어올 때 key=insert 같은 비밀번호를 살짝 보여줘
  • 이걸 보고, 입구(DispatcherServlet)가
    “아! 너는 가입 도우미한테 가야 해” 라고 알려줘
  • 비밀번호랑 도우미 이름을 연결한 표가 따로 있어. (이게 actionMapping.properties야)

🧳 4. 이 도우미들이 처음부터 있는 건 아니고...

  • 건물이 열릴 때 (서버 시작될 때)
  • HandlerMappingListener 라는 사람이
    그 표(actionMapping.properties)를 보고
    “자~ 가입 도우미, 검색 도우미, 수정 도우미 만들어서 준비해둘게~” 하고
    미리 만들어서 공용창고(application)에 보관해놔!

→ 그래서 손님이 왔을 때 바로 꺼내쓸 수 있어!


📦 5. 이 도우미들은 혼자 일 안 해

  • 자기 친구들한테 도움을 줘! (이게 Service, DAO)

    • 예: “야~ 저 친구 가입하려고 하는데, 이 정보 DB에 넣어줘~”
  • Service는 일 시키는 매니저 느낌이고,

  • DAO는 진짜 컴퓨터에 저장하는 친구야.


💡 정리하면!

  • 손님이 웹사이트에 요청함 (/front?key=insert)
  • 입구가 누군지 보고 도우미에게 안내
  • 도우미는 정보를 받고, 매니저(Service) → 저장 친구(DAO)에게 전달
  • 다 처리되면 다시 입구로 돌아와서 결과 페이지 보여줌 (index.jsp)

쉽게 이해했지?
이 웹 프로젝트는 정말 "회사처럼 역할 나눠서 일하는 구조" 라고 보면 돼!

또 궁금하면 언제든 물어봐도 돼~ 넌 점점 잘하고 있어 👏🔥

profile
@mgkick

0개의 댓글