[Spring] Request Mapping

배창민·2025년 10월 15일

Request Mapping

Spring Web MVC는 요청 → 컨트롤러 → 서비스/DAO → 모델 → 뷰 흐름을 표준화하고, DI 컨테이너가 레이어 간 의존을 관리해 유연한 웹 애플리케이션을 구성한다.


1) MVC 계층 한눈에 정리

  • Controller: 요청 수신, 파라미터 가공, 서비스 호출, Model 구성 후 뷰로 전달

  • Service: 비즈니스 로직, 트랜잭션/Connection 라이프사이클 관리

  • DAO: DB CRUD, JDBC/ORM로 데이터 접근 전담

  • 핵심 포인트

    • 트랜잭션은 하나의 Connection으로 일관되게 처리
    • ResultSet 등 DB 의존 타입은 DAO 내부에서만 사용하고 DTO/VO로 전달
    • 모델 중심 설계(Service 중심)로 재사용성과 유지보수성 향상

2) Spring MVC 요청 처리 플로우

  1. HTTP Request : 클라이언트의 Request가 DispatcherServlet에 도착한다.
  2. Handler 조회 : HandlerMapping을 통해 클라이언트의 요청을 매핑할 적절한 Controller를 찾는다.
  3. handle(handler) : 핸들러 어댑터를 실행한다. 핸들러 어댑터는 Controller와 DispatcherServlet 간 통신을 중개하며, DispatcherServlet이 Controller를 호출할 때 기능을 제공한다.
  4. handler 호출 : Controller의 handler method를 호출한다. Controller는 비즈니스 로직을 실행하고 Model 객체를 반환한다.
  5. ModelAndView 반환 : 핸들러 어댑터는 핸들러가 반환하는 정보를 ModelAndView로 변환해서 반환한다.
  6. View Resolver 호출 : DispatcherServlet은 ViewResolver를 통해 어떤 View를 사용할지 결정한다.
  7. View 반환 : 뷰 리졸버는 뷰의 이름을 통해 해당하는 뷰 객체를 반환한다.
  8. render(model) : View는 Model을 사용하여 뷰를 렌더링한다.
  9. HTTP Response : 클라이언트에게 응답을 반환한다.

주요 컴포넌트

구성요소역할
DispatcherServlet요청 중앙집중 처리, 핸들러 위임
HandlerMapping요청 ↔ 컨트롤러 매핑 결정
HandlerAdapter컨트롤러 호출 방식 추상화
Controller비즈니스 로직 트리거, 모델 생성
Model뷰에 전달할 데이터 컨테이너
ViewResolver뷰 탐색 및 선택
View모델 기반 렌더링

3) @RequestMapping 핵심

클래스/메서드 레벨에 선언하여 URL/HTTP 메서드/파라미터 조건을 매핑한다.

3-1) 기본 매핑 (메서드 미지정: GET/POST 모두 수락)

@Controller
public class MenuController {

  @RequestMapping("/menu/regist")
  public String registMenu(Model model) {
    model.addAttribute("message", "신규 메뉴 등록용 핸들러 메소드 호출함...");
    return "mappingResult"; // templates/mappingResult.html
  }
}

3-2) HTTP 메서드 제한

@RequestMapping(value = "/menu/modify", method = RequestMethod.GET)
public String modifyMenu(Model model) {
  model.addAttribute("message", "GET 방식의 메뉴 수정용 핸들러 메소드 호출함...");
  return "mappingResult";
}
  • 다른 메서드로 호출 시 405(Method Not Allowed)

3-3) 전용 단축 어노테이션 (since 4.3)

HTTP어노테이션
GET@GetMapping
POST@PostMapping
PUT@PutMapping
DELETE@DeleteMapping
PATCH@PatchMapping
@GetMapping("/menu/delete")
public String getDeleteMenu(Model model) { ... }

@PostMapping("/menu/delete")
public String postDeleteMenu(Model model) { ... }

3-4) 클래스 레벨 공통 경로

@Controller
@RequestMapping("/order/*")
public class OrderController {

  @GetMapping("/regist")
  public String registOrder(Model model) {
    model.addAttribute("message", "GET 주문 등록 핸들러 호출");
    return "mappingResult";
  }
}

3-5) 복수 패턴 매핑

@RequestMapping(value = {"modify", "delete"}, method = RequestMethod.POST)
public String modifyAndDelete(Model model) {
  model.addAttribute("message", "POST 수정/삭제 공통 처리");
  return "mappingResult";
}

3-6) @PathVariable 경로 변수

@GetMapping("/order/detail/{orderNo}")
public String selectOrderDetail(Model model, @PathVariable int orderNo) {
  model.addAttribute("message", orderNo + "번 주문 상세 조회");
  return "mappingResult";
}
  • 타입 불일치 시 400(Bad Request)
  • 세그먼트 누락 시 매핑 실패

3-7) 기본 핸들러 (URL 미지정)

@RequestMapping
public String otherRequest(Model model) {
  model.addAttribute("message", "order 요청이나 다른 기능은 준비되지 않음");
  return "mappingResult";
}

4) 뷰 렌더링 기본 (Thymeleaf 예)

<h3 th:text="${message}"></h3>

Model#addAttribute("message", ...) 로 전달한 값을 출력한다.


5) 체크리스트

  • URL 설계는 리소스 중심, 상태 변화는 적절한 HTTP 메서드로 구분
  • 공통 경로는 클래스 레벨 @RequestMapping, 세부는 메서드 레벨로 분리
  • 전용 매핑 어노테이션으로 가독성 확보 (@GetMapping 등)
  • 경로 변수는 타입 안전하게 매핑하고 유효성 고려
  • 서비스에서 트랜잭션Connection 라이프사이클 관리
  • DAO는 데이터 접근 전담, DB 의존 타입은 외부로 노출 금지
  • 뷰에는 Model 데이터만 전달, 렌더링 책임 분리
profile
개발자 희망자

0개의 댓글