[{"data":1,"prerenderedAt":1076},["ShallowReactive",2],{"post-document:\u002Fjava\u002Fspring\u002F2026\u002F08\u002F14\u002Fspring-mvc-request-flow\u002F":3},{"id":4,"title":5,"body":6,"categories":1056,"date":1058,"description":1059,"extension":1060,"image":1061,"key_concepts":1061,"last_modified_at":1061,"legacyPath":1062,"meta":1063,"navigation":367,"part":1065,"path":1066,"published":367,"robots":1061,"seo":1067,"series":1068,"stem":1069,"strengths":1061,"summary":1061,"tags":1070,"tradeoffs":1061,"__hash__":1075},"posts\u002Fposts\u002FBackend\u002FSPRING\u002FSpring\u002F2026-08-14-spring-mvc-request-flow.md","Spring 기초 Part 2: Spring MVC 요청 처리 흐름",{"type":7,"value":8,"toc":1042},"minimark",[9,13,20,23,34,37,43,46,51,181,183,187,190,246,249,285,288,294,296,300,303,309,317,323,326,328,332,335,399,402,413,416,422,425,444,449,537,539,543,547,550,626,629,632,635,704,707,710,724,727,729,738,743,749,791,797,802,807,848,851,881,933,935,939,944,950,952,956,1017,1022,1026,1038],[10,11,5],"h2",{"id":12},"spring-기초-part-2-spring-mvc-요청-처리-흐름",[14,15,16],"blockquote",{},[17,18,19],"p",{},"Spring MVC는 HTTP 요청을 적절한 Controller에 연결하고, 처리 결과를 View 또는 JSON으로 반환하는 웹 프레임워크다.",[17,21,22],{},"처음에는 다음 흐름부터 기억하면 된다.",[24,25,31],"pre",{"className":26,"code":28,"language":29,"meta":30},[27],"language-text","Client\n  → DispatcherServlet\n  → Controller\n  → Service\n  → Repository\n  → Database\n","text","",[32,33,28],"code",{"__ignoreMap":30},[17,35,36],{},"응답은 반대 방향으로 돌아온다.",[24,38,41],{"className":39,"code":40,"language":29,"meta":30},[27],"Database\n  → Repository\n  → Service\n  → Controller\n  → JSON 또는 HTML\n  → Client\n",[32,42,40],{"__ignoreMap":30},[44,45],"hr",{},[47,48,50],"h3",{"id":49},"_1-먼저-알아둘-단어","1. 먼저 알아둘 단어",[52,53,54,70],"table",{},[55,56,57],"thead",{},[58,59,60,64,67],"tr",{},[61,62,63],"th",{},"용어",[61,65,66],{},"정의",[61,68,69],{},"쉽게 말하면",[71,72,73,85,98,109,120,131,142,156,167],"tbody",{},[58,74,75,79,82],{},[76,77,78],"td",{},"Client",[76,80,81],{},"서버에 HTTP 요청을 보내는 프로그램",[76,83,84],{},"브라우저, Vue, React, 앱, Postman",[58,86,87,90,93],{},[76,88,89],{},"HTTP Request",[76,91,92],{},"Client가 서버에 보내는 요청",[76,94,95],{},[32,96,97],{},"GET \u002Fapi\u002Fusers\u002F1",[58,99,100,103,106],{},[76,101,102],{},"HTTP Response",[76,104,105],{},"서버가 Client에 돌려주는 결과",[76,107,108],{},"상태 코드와 JSON 데이터",[58,110,111,114,117],{},[76,112,113],{},"MVC",[76,115,116],{},"Model, View, Controller로 역할을 나누는 설계 방식",[76,118,119],{},"데이터, 화면, 요청 처리를 분리",[58,121,122,125,128],{},[76,123,124],{},"Servlet",[76,126,127],{},"Java 웹 서버에서 HTTP 요청과 응답을 처리하는 객체",[76,129,130],{},"Spring MVC의 입구를 만드는 기반 기술",[58,132,133,136,139],{},[76,134,135],{},"DispatcherServlet",[76,137,138],{},"Spring MVC의 모든 요청을 먼저 받는 Front Controller",[76,140,141],{},"요청을 담당 Controller에 배분하는 중앙 안내자",[58,143,144,147,150],{},[76,145,146],{},"HandlerMapping",[76,148,149],{},"요청을 처리할 Controller 메서드를 찾는 객체",[76,151,152,155],{},[32,153,154],{},"\u002Fusers\u002F1","을 누가 처리하는지 검색",[58,157,158,161,164],{},[76,159,160],{},"HandlerAdapter",[76,162,163],{},"찾은 Controller 메서드를 실제로 호출하는 객체",[76,165,166],{},"매개변수를 준비하고 메서드를 실행",[58,168,169,172,175],{},[76,170,171],{},"Jackson",[76,173,174],{},"자바 객체와 JSON을 변환하는 라이브러리",[76,176,177,180],{},[32,178,179],{},"UserDto","를 JSON으로 변환",[44,182],{},[47,184,186],{"id":185},"_2-mvc와-계층형-구조는-같은-말이-아니다","2. MVC와 계층형 구조는 같은 말이 아니다",[17,188,189],{},"기본 MVC는 역할을 다음처럼 구분한다.",[52,191,192,205],{},[55,193,194],{},[58,195,196,199,202],{},[61,197,198],{},"구성",[61,200,201],{},"역할",[61,203,204],{},"Spring에서의 예",[71,206,207,218,229],{},[58,208,209,212,215],{},[76,210,211],{},"Model",[76,213,214],{},"애플리케이션의 데이터와 상태",[76,216,217],{},"DTO, Entity, Service의 처리 결과",[58,219,220,223,226],{},[76,221,222],{},"View",[76,224,225],{},"사용자에게 보여줄 결과",[76,227,228],{},"HTML, Thymeleaf 화면",[58,230,231,234,237],{},[76,232,233],{},"Controller",[76,235,236],{},"요청을 받고 처리 흐름을 연결",[76,238,239,242,243],{},[32,240,241],{},"@Controller",", ",[32,244,245],{},"@RestController",[17,247,248],{},"실무의 Spring 애플리케이션에서는 유지보수를 위해 역할을 더 세분화한다.",[52,250,251,260],{},[55,252,253],{},[58,254,255,258],{},[61,256,257],{},"계층",[61,259,201],{},[71,261,262,269,277],{},[58,263,264,266],{},[76,265,233],{},[76,267,268],{},"HTTP 요청과 응답 처리",[58,270,271,274],{},[76,272,273],{},"Service",[76,275,276],{},"비즈니스 규칙과 트랜잭션 처리",[58,278,279,282],{},[76,280,281],{},"Repository",[76,283,284],{},"데이터베이스 접근",[17,286,287],{},"즉 Spring MVC와 계층형 구조를 함께 사용하는 것이다.",[24,289,292],{"className":290,"code":291,"language":29,"meta":30},[27],"Spring MVC\n→ HTTP 요청을 Controller에 연결하고 응답을 만드는 구조\n\n계층형 구조\n→ Controller, Service, Repository의 책임을 나누는 구조\n",[32,293,291],{"__ignoreMap":30},[44,295],{},[47,297,299],{"id":298},"_3-dispatcherservlet","3. DispatcherServlet",[17,301,302],{},"Client의 요청이 Controller로 바로 전달되는 것은 아니다.",[24,304,307],{"className":305,"code":306,"language":29,"meta":30},[27],"Client\n  → DispatcherServlet\n  → Controller\n",[32,308,306],{"__ignoreMap":30},[17,310,311,312,316],{},"DispatcherServlet은 모든 요청을 먼저 받고 적절한 Controller로 전달한다. 이런 구조를 ",[313,314,315],"strong",{},"Front Controller Pattern","이라고 한다.",[24,318,321],{"className":319,"code":320,"language":29,"meta":30},[27],"                       ┌→ UserController\nClient → DispatcherServlet → ProductController\n                       └→ OrderController\n",[32,322,320],{"__ignoreMap":30},[17,324,325],{},"각 Controller가 공통 처리를 직접 반복하지 않아도 DispatcherServlet을 중심으로 일관된 요청 처리가 가능하다.",[44,327],{},[47,329,331],{"id":330},"_4-handlermapping과-handleradapter","4. HandlerMapping과 HandlerAdapter",[17,333,334],{},"다음 Controller가 있다고 해보자.",[24,336,340],{"className":337,"code":338,"language":339,"meta":30,"style":30},"language-java shiki shiki-themes github-light github-dark","@RestController\n@RequestMapping(\"\u002Fapi\u002Fusers\")\npublic class UserController {\n\n    @GetMapping(\"\u002F{id}\")\n    public UserResponse getUser(@PathVariable Long id) {\n        \u002F\u002F 사용자 조회\n    }\n}\n","java",[32,341,342,350,356,362,369,375,381,387,393],{"__ignoreMap":30},[343,344,347],"span",{"class":345,"line":346},"line",1,[343,348,349],{},"@RestController\n",[343,351,353],{"class":345,"line":352},2,[343,354,355],{},"@RequestMapping(\"\u002Fapi\u002Fusers\")\n",[343,357,359],{"class":345,"line":358},3,[343,360,361],{},"public class UserController {\n",[343,363,365],{"class":345,"line":364},4,[343,366,368],{"emptyLinePlaceholder":367},true,"\n",[343,370,372],{"class":345,"line":371},5,[343,373,374],{},"    @GetMapping(\"\u002F{id}\")\n",[343,376,378],{"class":345,"line":377},6,[343,379,380],{},"    public UserResponse getUser(@PathVariable Long id) {\n",[343,382,384],{"class":345,"line":383},7,[343,385,386],{},"        \u002F\u002F 사용자 조회\n",[343,388,390],{"class":345,"line":389},8,[343,391,392],{},"    }\n",[343,394,396],{"class":345,"line":395},9,[343,397,398],{},"}\n",[17,400,401],{},"Client가 다음 요청을 보낸다.",[24,403,407],{"className":404,"code":405,"language":406,"meta":30,"style":30},"language-http shiki shiki-themes github-light github-dark","GET \u002Fapi\u002Fusers\u002F1\n","http",[32,408,409],{"__ignoreMap":30},[343,410,411],{"class":345,"line":346},[343,412,405],{},[17,414,415],{},"Spring은 애플리케이션을 시작할 때 어노테이션 정보를 읽고 URL과 메서드의 연결 정보를 준비한다.",[24,417,420],{"className":418,"code":419,"language":29,"meta":30},[27],"GET \u002Fapi\u002Fusers\u002F{id}\n        ↓\nUserController.getUser()\n",[32,421,419],{"__ignoreMap":30},[17,423,424],{},"실행 시 각 객체의 역할은 다음과 같다.",[426,427,428,432,435,438,441],"ol",{},[429,430,431],"li",{},"DispatcherServlet이 요청을 받는다.",[429,433,434],{},"HandlerMapping이 요청을 처리할 Controller 메서드를 찾는다.",[429,436,437],{},"HandlerAdapter가 필요한 매개변수를 준비한다.",[429,439,440],{},"HandlerAdapter가 Controller 메서드를 호출한다.",[429,442,443],{},"반환 결과를 DispatcherServlet이 응답으로 처리한다.",[17,445,446],{},[313,447,448],{},"Spring MVC REST API 요청 흐름",[24,450,454],{"className":451,"code":452,"language":453,"meta":30,"style":30},"language-mermaid shiki shiki-themes github-light github-dark","flowchart LR\n    C[Client] -->|HTTP Request| D[DispatcherServlet]\n    D -->|처리 대상 검색| HM[HandlerMapping]\n    HM -->|Controller 정보| D\n    D -->|실행 요청| HA[HandlerAdapter]\n    HA --> CT[Controller]\n    CT --> S[Service]\n    S --> R[Repository]\n    R --> DB[(Database)]\n    DB --> R\n    R --> S\n    S --> CT\n    CT -->|Java Object| HA\n    HA --> D\n    D -->|JSON Response| C\n","mermaid",[32,455,456,461,466,471,476,481,486,491,496,501,507,513,519,525,531],{"__ignoreMap":30},[343,457,458],{"class":345,"line":346},[343,459,460],{},"flowchart LR\n",[343,462,463],{"class":345,"line":352},[343,464,465],{},"    C[Client] -->|HTTP Request| D[DispatcherServlet]\n",[343,467,468],{"class":345,"line":358},[343,469,470],{},"    D -->|처리 대상 검색| HM[HandlerMapping]\n",[343,472,473],{"class":345,"line":364},[343,474,475],{},"    HM -->|Controller 정보| D\n",[343,477,478],{"class":345,"line":371},[343,479,480],{},"    D -->|실행 요청| HA[HandlerAdapter]\n",[343,482,483],{"class":345,"line":377},[343,484,485],{},"    HA --> CT[Controller]\n",[343,487,488],{"class":345,"line":383},[343,489,490],{},"    CT --> S[Service]\n",[343,492,493],{"class":345,"line":389},[343,494,495],{},"    S --> R[Repository]\n",[343,497,498],{"class":345,"line":395},[343,499,500],{},"    R --> DB[(Database)]\n",[343,502,504],{"class":345,"line":503},10,[343,505,506],{},"    DB --> R\n",[343,508,510],{"class":345,"line":509},11,[343,511,512],{},"    R --> S\n",[343,514,516],{"class":345,"line":515},12,[343,517,518],{},"    S --> CT\n",[343,520,522],{"class":345,"line":521},13,[343,523,524],{},"    CT -->|Java Object| HA\n",[343,526,528],{"class":345,"line":527},14,[343,529,530],{},"    HA --> D\n",[343,532,534],{"class":345,"line":533},15,[343,535,536],{},"    D -->|JSON Response| C\n",[44,538],{},[47,540,542],{"id":541},"_5-controller-service-repository","5. Controller, Service, Repository",[544,545,233],"h4",{"id":546},"controller",[17,548,549],{},"Controller는 HTTP 요청과 응답에 집중한다.",[24,551,553],{"className":337,"code":552,"language":339,"meta":30,"style":30},"@RestController\n@RequestMapping(\"\u002Fapi\u002Fusers\")\npublic class UserController {\n\n    private final UserService userService;\n\n    public UserController(UserService userService) {\n        this.userService = userService;\n    }\n\n    @GetMapping(\"\u002F{id}\")\n    public ResponseEntity\u003CUserResponse> getUser(@PathVariable Long id) {\n        UserResponse response = userService.getUser(id);\n        return ResponseEntity.ok(response);\n    }\n}\n",[32,554,555,559,563,567,571,576,580,585,590,594,598,602,607,612,617,621],{"__ignoreMap":30},[343,556,557],{"class":345,"line":346},[343,558,349],{},[343,560,561],{"class":345,"line":352},[343,562,355],{},[343,564,565],{"class":345,"line":358},[343,566,361],{},[343,568,569],{"class":345,"line":364},[343,570,368],{"emptyLinePlaceholder":367},[343,572,573],{"class":345,"line":371},[343,574,575],{},"    private final UserService userService;\n",[343,577,578],{"class":345,"line":377},[343,579,368],{"emptyLinePlaceholder":367},[343,581,582],{"class":345,"line":383},[343,583,584],{},"    public UserController(UserService userService) {\n",[343,586,587],{"class":345,"line":389},[343,588,589],{},"        this.userService = userService;\n",[343,591,592],{"class":345,"line":395},[343,593,392],{},[343,595,596],{"class":345,"line":503},[343,597,368],{"emptyLinePlaceholder":367},[343,599,600],{"class":345,"line":509},[343,601,374],{},[343,603,604],{"class":345,"line":515},[343,605,606],{},"    public ResponseEntity\u003CUserResponse> getUser(@PathVariable Long id) {\n",[343,608,609],{"class":345,"line":521},[343,610,611],{},"        UserResponse response = userService.getUser(id);\n",[343,613,614],{"class":345,"line":527},[343,615,616],{},"        return ResponseEntity.ok(response);\n",[343,618,619],{"class":345,"line":533},[343,620,392],{},[343,622,624],{"class":345,"line":623},16,[343,625,398],{},[17,627,628],{},"Controller에는 복잡한 업무 규칙을 넣지 않는다.",[544,630,273],{"id":631},"service",[17,633,634],{},"Service는 실제 업무 규칙을 처리한다.",[24,636,638],{"className":337,"code":637,"language":339,"meta":30,"style":30},"@Service\npublic class UserService {\n\n    private final UserRepository userRepository;\n\n    public UserService(UserRepository userRepository) {\n        this.userRepository = userRepository;\n    }\n\n    public UserResponse getUser(Long id) {\n        User user = userRepository.findById(id).orElseThrow();\n        return UserResponse.from(user);\n    }\n}\n",[32,639,640,645,650,654,659,663,668,673,677,681,686,691,696,700],{"__ignoreMap":30},[343,641,642],{"class":345,"line":346},[343,643,644],{},"@Service\n",[343,646,647],{"class":345,"line":352},[343,648,649],{},"public class UserService {\n",[343,651,652],{"class":345,"line":358},[343,653,368],{"emptyLinePlaceholder":367},[343,655,656],{"class":345,"line":364},[343,657,658],{},"    private final UserRepository userRepository;\n",[343,660,661],{"class":345,"line":371},[343,662,368],{"emptyLinePlaceholder":367},[343,664,665],{"class":345,"line":377},[343,666,667],{},"    public UserService(UserRepository userRepository) {\n",[343,669,670],{"class":345,"line":383},[343,671,672],{},"        this.userRepository = userRepository;\n",[343,674,675],{"class":345,"line":389},[343,676,392],{},[343,678,679],{"class":345,"line":395},[343,680,368],{"emptyLinePlaceholder":367},[343,682,683],{"class":345,"line":503},[343,684,685],{},"    public UserResponse getUser(Long id) {\n",[343,687,688],{"class":345,"line":509},[343,689,690],{},"        User user = userRepository.findById(id).orElseThrow();\n",[343,692,693],{"class":345,"line":515},[343,694,695],{},"        return UserResponse.from(user);\n",[343,697,698],{"class":345,"line":521},[343,699,392],{},[343,701,702],{"class":345,"line":527},[343,703,398],{},[544,705,281],{"id":706},"repository",[17,708,709],{},"Repository는 데이터베이스 접근을 담당한다.",[24,711,713],{"className":337,"code":712,"language":339,"meta":30,"style":30},"public interface UserRepository extends JpaRepository\u003CUser, Long> {\n}\n",[32,714,715,720],{"__ignoreMap":30},[343,716,717],{"class":345,"line":346},[343,718,719],{},"public interface UserRepository extends JpaRepository\u003CUser, Long> {\n",[343,721,722],{"class":345,"line":352},[343,723,398],{},[17,725,726],{},"역할을 나누면 HTTP 처리, 업무 규칙, DB 접근을 각각 독립적으로 수정하고 테스트하기 쉬워진다.",[44,728],{},[47,730,732,733,735,736],{"id":731},"_6-controller와-restcontroller","6. ",[32,734,241],{},"와 ",[32,737,245],{},[544,739,741],{"id":740},"controller-1",[32,742,241],{},[17,744,745,746,748],{},"일반적인 ",[32,747,241],{},"가 문자열을 반환하면 View 이름으로 해석할 수 있다.",[24,750,752],{"className":337,"code":751,"language":339,"meta":30,"style":30},"@Controller\npublic class HomeController {\n\n    @GetMapping(\"\u002F\")\n    public String home() {\n        return \"home\";\n    }\n}\n",[32,753,754,759,764,768,773,778,783,787],{"__ignoreMap":30},[343,755,756],{"class":345,"line":346},[343,757,758],{},"@Controller\n",[343,760,761],{"class":345,"line":352},[343,762,763],{},"public class HomeController {\n",[343,765,766],{"class":345,"line":358},[343,767,368],{"emptyLinePlaceholder":367},[343,769,770],{"class":345,"line":364},[343,771,772],{},"    @GetMapping(\"\u002F\")\n",[343,774,775],{"class":345,"line":371},[343,776,777],{},"    public String home() {\n",[343,779,780],{"class":345,"line":377},[343,781,782],{},"        return \"home\";\n",[343,784,785],{"class":345,"line":383},[343,786,392],{},[343,788,789],{"class":345,"line":389},[343,790,398],{},[24,792,795],{"className":793,"code":794,"language":29,"meta":30},[27],"return \"home\"\n   → ViewResolver\n   → home.html 검색\n   → HTML 응답\n",[32,796,794],{"__ignoreMap":30},[544,798,800],{"id":799},"restcontroller",[32,801,245],{},[17,803,804,806],{},[32,805,245],{},"의 반환값은 기본적으로 HTTP 응답 본문으로 전달된다.",[24,808,810],{"className":337,"code":809,"language":339,"meta":30,"style":30},"@RestController\npublic class HelloController {\n\n    @GetMapping(\"\u002Fapi\u002Fhello\")\n    public MessageResponse hello() {\n        return new MessageResponse(\"hello\");\n    }\n}\n",[32,811,812,816,821,825,830,835,840,844],{"__ignoreMap":30},[343,813,814],{"class":345,"line":346},[343,815,349],{},[343,817,818],{"class":345,"line":352},[343,819,820],{},"public class HelloController {\n",[343,822,823],{"class":345,"line":358},[343,824,368],{"emptyLinePlaceholder":367},[343,826,827],{"class":345,"line":364},[343,828,829],{},"    @GetMapping(\"\u002Fapi\u002Fhello\")\n",[343,831,832],{"class":345,"line":371},[343,833,834],{},"    public MessageResponse hello() {\n",[343,836,837],{"class":345,"line":377},[343,838,839],{},"        return new MessageResponse(\"hello\");\n",[343,841,842],{"class":345,"line":383},[343,843,392],{},[343,845,846],{"class":345,"line":389},[343,847,398],{},[17,849,850],{},"Jackson이 자바 객체를 JSON으로 변환한다.",[24,852,856],{"className":853,"code":854,"language":855,"meta":30,"style":30},"language-json shiki shiki-themes github-light github-dark","{\n  \"message\": \"hello\"\n}\n","json",[32,857,858,864,877],{"__ignoreMap":30},[343,859,860],{"class":345,"line":346},[343,861,863],{"class":862},"sVt8B","{\n",[343,865,866,870,873],{"class":345,"line":352},[343,867,869],{"class":868},"sj4cs","  \"message\"",[343,871,872],{"class":862},": ",[343,874,876],{"class":875},"sZZnC","\"hello\"\n",[343,878,879],{"class":345,"line":358},[343,880,398],{"class":862},[52,882,883,898],{},[55,884,885],{},[58,886,887,890,894],{},[61,888,889],{},"구분",[61,891,892],{},[32,893,241],{},[61,895,896],{},[32,897,245],{},[71,899,900,911,922],{},[58,901,902,905,908],{},[76,903,904],{},"주요 목적",[76,906,907],{},"HTML View 반환",[76,909,910],{},"JSON 데이터 반환",[58,912,913,916,919],{},[76,914,915],{},"반환값 처리",[76,917,918],{},"View 이름으로 해석 가능",[76,920,921],{},"Response Body로 변환",[58,923,924,927,930],{},[76,925,926],{},"주 사용처",[76,928,929],{},"서버 렌더링 웹 페이지",[76,931,932],{},"REST API",[44,934],{},[47,936,938],{"id":937},"_7-전체-실행-흐름","7. 전체 실행 흐름",[17,940,941,943],{},[32,942,97],{}," 요청을 다시 연결하면 다음과 같다.",[24,945,948],{"className":946,"code":947,"language":29,"meta":30},[27],"1. Client가 GET \u002Fapi\u002Fusers\u002F1 요청\n2. DispatcherServlet이 요청 수신\n3. HandlerMapping이 UserController.getUser() 검색\n4. HandlerAdapter가 id 값을 준비하고 메서드 호출\n5. Controller가 UserService 호출\n6. Service가 UserRepository 호출\n7. Repository가 DB 조회\n8. 조회 결과가 Repository → Service → Controller로 반환\n9. Jackson이 UserResponse를 JSON으로 변환\n10. Client에 HTTP 응답 반환\n",[32,949,947],{"__ignoreMap":30},[44,951],{},[47,953,955],{"id":954},"핵심-정리","핵심 정리",[52,957,958,968],{},[55,959,960],{},[58,961,962,965],{},[61,963,964],{},"구성 요소",[61,966,967],{},"핵심 역할",[71,969,970,977,984,991,997,1004,1010],{},[58,971,972,974],{},[76,973,135],{},[76,975,976],{},"모든 요청을 먼저 받는 Front Controller",[58,978,979,981],{},[76,980,146],{},[76,982,983],{},"요청을 처리할 Controller 메서드 검색",[58,985,986,988],{},[76,987,160],{},[76,989,990],{},"Controller 메서드 실행",[58,992,993,995],{},[76,994,233],{},[76,996,268],{},[58,998,999,1001],{},[76,1000,273],{},[76,1002,1003],{},"비즈니스 규칙 처리",[58,1005,1006,1008],{},[76,1007,281],{},[76,1009,284],{},[58,1011,1012,1014],{},[76,1013,171],{},[76,1015,1016],{},"자바 객체를 JSON으로 변환",[14,1018,1019],{},[17,1020,1021],{},"Spring MVC의 핵심은 요청을 Controller에 연결하는 흐름과 Controller, Service, Repository의 책임을 분리하는 데 있다.",[47,1023,1025],{"id":1024},"참고-자료","참고 자료",[1027,1028,1029],"ul",{},[429,1030,1031],{},[1032,1033,1037],"a",{"href":1034,"rel":1035},"https:\u002F\u002Fdocs.spring.io\u002Fspring-framework\u002Freference\u002Fweb\u002Fwebmvc.html",[1036],"nofollow","Spring Framework Web MVC 공식 문서",[1039,1040,1041],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}",{"title":30,"searchDepth":352,"depth":352,"links":1043},[1044],{"id":12,"depth":352,"text":5,"children":1045},[1046,1047,1048,1049,1050,1051,1053,1054,1055],{"id":49,"depth":358,"text":50},{"id":185,"depth":358,"text":186},{"id":298,"depth":358,"text":299},{"id":330,"depth":358,"text":331},{"id":541,"depth":358,"text":542},{"id":731,"depth":358,"text":1052},"6. @Controller와 @RestController",{"id":937,"depth":358,"text":938},{"id":954,"depth":358,"text":955},{"id":1024,"depth":358,"text":1025},[339,1057],"spring","2026-08-14 09:00:00 +0900","DispatcherServlet부터 Controller, Service, Repository, JSON 응답까지 Spring MVC의 전체 요청 흐름을 정리한다.","md",null,"\u002Fjava\u002Fspring\u002F2026\u002F08\u002F14\u002Fspring-mvc-request-flow\u002F",{"layout":1064},"post","2","\u002Fposts\u002Fbackend\u002Fspring\u002Fspring\u002F2026-08-14-spring-mvc-request-flow",{"title":5,"description":1059},"Spring 기초","posts\u002FBackend\u002FSPRING\u002FSpring\u002F2026-08-14-spring-mvc-request-flow",[1071,1072,1073,1074,135,932],"Java","Spring","Spring Boot","Spring MVC","Sf5CLLXT7QIspw2r2rXLTczTMzXCu4S-iqitDzLMAjc",1788744786127]