02.MVC
Spring MVC Framework
MVC Pattern
Model
View ์ ์ถ๋ ฅํ ๋ฐ์ดํฐ๋ฅผ ๋ด๋ ์ญํ (View ๋ ํ๋ฉด ๋ ๋๋ง์๋ง ์ง์ค)
View
Model ์ ๋ด๊ฒจ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํด์ ํ๋ฉด(HTML)์ ๊ทธ๋ฆฌ๋ ์ญํ
Controller
HTTP ์์ฒญ์ ๋ฐ์์ ํ๋ผ๋ฏธํฐ๋ฅผ ๊ฒ์ฆํ๊ณ , ๋น์ฆ๋์ค ๋ก์ง์ ์คํํ๋ ์ญํ
์ ๋ฌํ ๋ฐ์ดํฐ๋ฅผ ์กฐํํด์ Model ์ ํตํด View ๋ก ์ ๋ฌ
์คํ๋ง MVC ์ ์ฒด ๊ตฌ์กฐ

DispacherServlet
DispatcherServlet โ FrameworkServlet โ HttpServletBean โ HttpServlet
์คํ๋ง ๋ถํธ๋ DispacherServlet ์ ์๋ธ๋ฆฟ์ผ๋ก ์๋์ผ๋ก ๋ฑ๋กํ๊ณ , ๋ชจ๋ ๊ฒฝ๋ก(urlPatterns="/")๋ฅผ ๋งคํ
DispacherServlet.doDispatch() ์ฐธ๊ณ
ํธ๋ค๋ฌ ์กฐํ : ํธ๋ค๋ฌ ๋งคํ์ ํตํด ์์ฒญ URL์ ๋งคํ๋ ํธ๋ค๋ฌ(์ปจํธ๋กค๋ฌ)๋ฅผ ์กฐํ
ํธ๋ค๋ฌ ์ด๋ํฐ ์กฐํ : ํธ๋ค๋ฌ๋ฅผ ์คํํ ์ ์๋ ํธ๋ค๋ฌ ์ด๋ํฐ๋ฅผ ์กฐํ
ํธ๋ค๋ฌ ์ด๋ํฐ ์คํ : ํธ๋ค๋ฌ ์ด๋ํฐ๋ฅผ ์คํ
ํธ๋ค๋ฌ ์คํ : ํธ๋ค๋ฌ ์ด๋ํฐ๊ฐ ์ค์ ํธ๋ค๋ฌ๋ฅผ ์คํ
ModelAndView ๋ฐํ : ํธ๋ค๋ฌ ์ด๋ํฐ๋ ํธ๋ค๋ฌ๊ฐ ๋ฐํํ๋ ์ ๋ณด๋ฅผ ModelAndView๋ก ๋ณํํด์ ๋ฐํ
viewResolver ํธ์ถ : viewResolver๋ฅผ ์ฐพ๊ณ ์คํ (JSP์ ๊ฒฝ์ฐ InternalResourceViewResolver ๊ฐ ์๋ ๋ฑ๋ก&์ฌ์ฉ)
View ๋ฐํ : viewResolver๋ ๋ทฐ์ ๋ ผ๋ฆฌ ์ด๋ฆ์ ๋ฌผ๋ฆฌ ์ด๋ฆ์ผ๋ก ๋ฐ๊พธ๊ณ , ๋ ๋๋ง ์ญํ ์ ๋ด๋นํ๋ ๋ทฐ ๊ฐ์ฒด ๋ฐํ (JSP์ ๊ฒฝ์ฐ InternalResourceView(JstlView) ๋ฅผ ๋ฐํํ๋๋ฐ, ๋ด๋ถ์ forward() ๋ก์ง ์กด์ฌ)
๋ทฐ ๋ ๋๋ง : ๋ทฐ๋ฅผ ํตํด์ ๋ทฐ๋ฅผ ๋ ๋๋ง
์ฃผ์ ์ธํฐํ์ด์ค
HandlerMapping
, HandlerAdapter
, ViewResolver
, View
HandlerMapping & HandlerAdapter
์ปจํธ๋กค๋ฌ ํธ์ถ ๊ณผ์
(1) ํธ๋ค๋ฌ ๋งคํ์ผ๋ก ํธ๋ค๋ฌ ์กฐํ
HandlerMapping ์ ์์๋๋ก ์คํํด์, ํธ๋ค๋ฌ ์ฐพ๊ธฐ
RequestMappingHandlerMapping : ์ ๋ ธํ ์ด์ ๊ธฐ๋ฐ์ ์ปจํธ๋กค๋ฌ์ธ @RequestMapping์์ ์ฌ์ฉ
BeanNameUrlHandlerMapping : ์คํ๋ง ๋น์ ์ด๋ฆ์ผ๋ก ํธ๋ค๋ฌ๋ฅผ ์ฐพ๋๋ค.
๋น ์ด๋ฆ์ผ๋ก ํธ๋ค๋ฌ๋ฅผ ์ฐพ์ ๊ฒฝ์ฐ, ๋น ์ด๋ฆ์ผ๋ก ํธ๋ค๋ฌ๋ฅผ ์ฐพ์์ฃผ๋ BeanNameUrlHandlerMapping ๊ฐ ์คํ์ ์ฑ๊ณตํ๊ณ ํธ๋ค๋ฌ์ธ Controller ๋ฅผ ๋ฐํ
(2) ํธ๋ค๋ฌ ์ด๋ํฐ ์กฐํ
HandlerAdapter ์ supports() ๋ฅผ ์์๋๋ก ํธ์ถ
RequestMappingHandlerAdapter : ์ ๋ ธํ ์ด์ ๊ธฐ๋ฐ์ ์ปจํธ๋กค๋ฌ์ธ @RequestMapping์์์ฌ์ฉ
HttpRequestHandlerAdapter : HttpRequestHandler ์ฒ๋ฆฌ
SimpleControllerHandlerAdapter : Controller ์ธํฐํ์ด์ค (์ ๋ ธํ ์ด์ X, ๊ณผ๊ฑฐ์ ์ฌ์ฉ) ์ฒ๋ฆฌ
SimpleControllerHandlerAdapter ๊ฐ Controller ์ธํฐํ์ด์ค๋ฅผ ์ง์ํ๋ฏ๋ก ๋์์ด ๋๋ค.
(3) ํธ๋ค๋ฌ ์ด๋ํฐ ์คํ
๋์คํจ์ฒ ์๋ธ๋ฆฟ์ด ์กฐํํ SimpleControllerHandlerAdapter ๋ฅผ ์คํํ๋ฉด์ ํธ๋ค๋ฌ ์ ๋ณด๋ ํจ๊ป ๋๊ฒจ์ค๋ค.
SimpleControllerHandlerAdapter ๋ ํธ๋ค๋ฌ์ธ Controller ๋ฅผ ๋ด๋ถ์์ ์คํํ๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํ
ViewResolver
ViewResolver ํธ์ถ ๊ณผ์
(1) ํธ๋ค๋ฌ ์ด๋ํฐ ํธ์ถ
ํธ๋ค๋ฌ ์ด๋ํฐ๋ฅผ ํตํด ๋ ผ๋ฆฌ ๋ทฐ ์ด๋ฆ์ ํ๋
(2) ViewResolver ํธ์ถ
๋ ผ๋ฆฌ ๋ทฐ ์ด๋ฆ์ผ๋ก viewResolver๋ฅผ ์์๋๋ก ํธ์ถ
BeanNameViewResolver : ๋น ์ด๋ฆ์ผ๋ก ๋ทฐ๋ฅผ ์ฐพ์์ ๋ฐํ
InternalResourceViewResolver : JSP๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ ๋ทฐ๋ฅผ ๋ฐํ
๋ ผ๋ฆฌ ๋ทฐ ์ด๋ฆ์ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋ก๋ ๋ทฐ๊ฐ ์๋ค๋ฉด InternalResourceViewResolver ๊ฐ ํธ์ถ
(3)InternalResourceViewResolver
InternalResourceView ๋ฅผ ๋ฐํ
(4) ๋ทฐ - InternalResourceView
InternalResourceView ๋ JSP์ฒ๋ผ ํฌ์๋ forward() ๋ฅผ ํธ์ถํด์ ์ฒ๋ฆฌํ ์ ์๋ ๊ฒฝ์ฐ์ ์ฌ์ฉ
(5) view.render() view.render() ๊ฐ ํธ์ถ๋๊ณ InternalResourceView ๋ forward() ๋ฅผ ์ฌ์ฉํด์ JSP๋ฅผ ์คํ
Spring MVC ๊ธฐ๋ณธ ๊ธฐ๋ฅ
ํ๋ก์ ํธ ์ค์
Jar ์ฌ์ฉ ์ ํญ์ ๋ด์ฅ ์๋ฒ(tomcat..)๋ฅผ ์ฌ์ฉ (๋ด์ฅ ์๋ฒ ์ต์ ํ)
War ์ฌ์ฉ ์ ์ฃผ๋ก ์ธ๋ถ ์๋ฒ์ ๋ฐฐํฌํ๋ ๋ชฉ์ ์ผ๋ก ์ฌ์ฉ
Logging
SpringBoot ๊ฐ ๊ธฐ๋ณธ์ผ๋ก ์ ๊ณตํ๋ Logback ์ ๋๋ถ๋ถ ์ฌ์ฉ
SLF4J interface ์ ๊ตฌํ์ฒด์ธ Logback
๋ก๊ทธ ๋ ๋ฒจ ์ค์
application.properties ์์ log level ์ค์ ๊ฐ๋ฅ
TRACE > DEBUG > INFO > WARN > ERROR
๋ณดํต ๊ฐ๋ฐ ์๋ฒ๋ debug, ์ด์ ์๋ฒ๋ info level
# ์ ์ฒด ๋ก๊ทธ ๋ ๋ฒจ ์ค์ (default: info) logging.level.root=info # ํน์ ํจํค์ง์ ๊ทธ ํ์ ๋ก๊ทธ ๋ ๋ฒจ ์ ์ logging.level.hello.springmvc=trace
๋ก๊ทธ ์ ์ธ
Lombok ์ฌ์ฉ ์
@Slf4j
java ์ฝ๋๋ก ์ ์ธ ์
private final Logger log = LoggerFactory.getLogger(getClass()); // OR private static final Logger log = LoggerFactory.getLogger(Xxx.class)
๋ก๊ทธ ํธ์ถ
// 2021-08-31 22:11:10.267 INFO 6688 --- [nio-8080-exec-6] hello.springmvc.basic.LogTestController : info log = Spring // ์๊ฐ / ๋ก๊ทธ / ํ๋ก์ธ์ค ID / Thread Name / Class Name // Message log.trace(" trace log = {}", name); log.debug(" debug log = {}", name); log.info(" info log = {}", name); log.warn(" warn log = {}", name); log.error(" error log = {}", name);
์์ฒญ ๋งคํ
Controller Annotation
@Controller : ๋ฐํ ๊ฐ์ด String ์ด๋ฉด ๋ทฐ ์ด๋ฆ์ผ๋ก ์ธ์(๋ทฐ๋ฅผ ์ฐพ๊ณ ๋๋๋ง)
@RestController : ๋ฐํ ๊ฐ์ผ๋ก ๋ทฐ๋ฅผ ์ฐพ๋ ๊ฒ์ด ์๋๋ผ, HTTP ๋ฉ์์ง ๋ฐ๋์ ๋ฐ๋ก ์ ๋ ฅ
์ถ์ฝ Annotation
/** * ํ์ ๋ชฉ๋ก ์กฐํ: GET /users * ํ์ ๋ฑ๋ก: POST /users * ํ์ ์กฐํ: GET /users/{userId} * ํ์ ์์ : PATCH /users/{userId} * ํ์ ์ญ์ : DELETE /users/{userId} */ @GetMapping(value = "/mapping-get-v2") public String mappingGetV2() { log.info("mapping-get-v2"); return "ok"; }
@PathVariable : ์ต๊ทผ HTTP API๋ ๋ฆฌ์์ค ๊ฒฝ๋ก์ ์๋ณ์๋ฅผ ๋ฃ๋ ์คํ์ผ์ ์ ํธ
@GetMapping("/mapping/users/{userId}/orders/{orderId}") public String mappingPath(@PathVariable String userId, @PathVariable Long orderId) { log.info("mappingPath userId={}, orderId={}", userId, orderId); return "ok"; }
ํน์ ํ๋ผ๋ฏธํฐ/ํค๋๋ก ์ถ๊ฐ ๋งคํ
ํ๋ผ๋ฏธํฐ์ ๊ฒฝ์ฐ params, ํค๋์ ๊ฒฝ์ฐ headers
params = {"mode=debug","data=good"}
/** * headers="mode", * headers="!mode" * headers="mode=debug" * headers="mode!=debug" (! = ) */ @GetMapping(value = "/mapping-header", headers = "mode=debug") public String mappingHeader() { log.info("mappingHeader"); return "ok"; }
Content-Type ํค๋ ๊ธฐ๋ฐ ์ถ๊ฐ ๋งคํ Media Type
Server ์ ์ฅ์์ ํน์ Media Type๋ง ๋ฐ์ ์ ์๋ค๊ณ ์์ฒญ ํค๋์ Content-Type์ผ๋ก ์ ๋ฌ
/** * Content-Type ํค๋ ๊ธฐ๋ฐ ์ถ๊ฐ ๋งคํ Media Type * consumes="application/json" * consumes="!application/json" * consumes="application/*" * consumes="*\/*" * MediaType.APPLICATION_JSON_VALUE */ @PostMapping(value = "/mapping-consume", consumes = MediaType.APPLICATION_JSON_VALUE) public String mappingConsumes() { log.info("mappingConsumes"); return "ok"; }
Accept ํค๋ ๊ธฐ๋ฐ Media Type
Client ์ ์ฅ์์ ํน์ Media Type๋ง ๋ฐ์ ์ ์๋ค๊ณ ์์ฒญ ํค๋์ Accept๋ก ์ ๋ฌ
/** * Accept ํค๋ ๊ธฐ๋ฐ Media Type * produces = "text/html" * produces = "!text/html" * produces = "text/*" * produces = "*\/*" */ @PostMapping(value = "/mapping-produce", produces = MediaType.TEXT_HTML_VALUE) public String mappingProduces() { log.info("mappingProduces"); return "ok"; }
HTTP Request
HttpServletRequest request
HttpServletResponse response
HttpMethod httpMethod
HTTP ๋ฉ์๋๋ฅผ ์กฐํ (org.springframework.http.HttpMethod)
Locale locale
Locale ์ ๋ณด๋ฅผ ์กฐํ
@RequestHeader MultiValueMap<String, String> headerMap
๋ชจ๋ HTTP ํค๋๋ฅผ MultiValueMap ํ์์ผ๋ก ์กฐํ
@RequestHeader("host") String host
ํน์ HTTP ํค๋๋ฅผ ์กฐํ
์์ฑ (required, defaultValue)
@CookieValue(value = "myCookie", required = false) String cookie
ํน์ ์ฟ ํค๋ฅผ ์กฐํ
์์ฑ (required, defaultValue)
Http Request Data
ํด๋ผ์ด์ธํธ์์ ์๋ฒ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๋ฐฉ๋ฒ
GET - Query Parameter
/url?username=hello&age=20
URL Query Parameter์ ๋ฐ์ดํฐ๋ฅผ ํฌํจํด์ ์ ๋ฌ
ex) ๊ฒ์, ํํฐ, ํ์ด์ง ๋ฑ
POST - HTML Form
content-type: application/x-www-form-urlencoded
Message Body์ Query Parameter ํ์์ผ๋ก ์ ๋ฌ (username=hello&age=20)
ex) ํ์ ๊ฐ์ , ์ํ ์ฃผ๋ฌธ, HTML Form
HTTP message body์ ๋ฐ์ดํฐ๋ฅผ ์ง์ ๋ด์์ ์์ฒญ
HTTP API์์ ์ฃผ๋ก ์ฌ์ฉ, JSON, XML, TEXT
POST, PUT, PATCH
@RequestParam
Get, Post ๋ฐฉ์์ Query Parameter binding
@RequestParam(value="name" required = false, defaultValue = "-1") String name
ํ๋ผ๋ฏธํฐ ์ด๋ฆ์ผ๋ก ๋ฐ์ธ๋ฉ
request.getParameter("name") ์ ๋์ผํ ํจ๊ณผ
์๋ต
HTTP ํ๋ผ๋ฏธํฐ ์ด๋ฆ์ด ๋ณ์ ์ด๋ฆ๊ณผ ๊ฐ์ผ๋ฉด value name ์๋ต ๊ฐ๋ฅ
String, int ๋ฑ ๋จ์ ํ์ ์ด๋ฉด @RequestParam ์๋ต ๊ฐ๋ฅ
required
ํ๋ผ๋ฏธํฐ ํ์ ์ฌ๋ถ (default = true )
defaultValue
๊ธฐ๋ณธ ๊ฐ ์ ์ฉ (๋น ๋ฌธ์๋ ๊ธฐ๋ณธ ๊ฐ์ผ๋ก ์ฒ๋ฆฌ)
requestParamMap
๋ชจ๋ ์์ฒญ ํ๋ผ๋ฏธํฐ ๋ฐ๊ธฐ
@RequestParam Map<String, Object> paramMap
paramMap.get("username")
ํ๋ผ๋ฏธํฐ ๊ฐ์ด ์ฌ๋ฌ๊ฐ๋ผ๋ฉด MultiValueMap ์ฌ์ฉ
@ResponseBody
String return ์ View ์กฐํ๋ฅผ ๋ฌด์ํ๊ณ , HTTP message body์ ์ง์ ํด๋น ๋ด์ฉ ์ ๋ ฅ
@ModelAttribute
๋ฐ์ธ๋ฉํ ๊ฐ์ฒด ์์ฑ
์์ฒญ ํ๋ผ๋ฏธํฐ์ ์ด๋ฆ์ผ๋ก ๋ฐ์ธ๋ฉ ๊ฐ์ฒด์ ํ๋กํผํฐ๋ฅผ ์ฐพ๊ณ , ํด๋น ํ๋กํผํฐ์ setter๋ฅผ ํธ์ถํด์ ํ๋ผ๋ฏธํฐ์ ๊ฐ์ ์ ๋ ฅ(๋ฐ์ธ๋ฉ)
ex) ํ๋ผ๋ฏธํฐ ์ด๋ฆ์ด username ์ด๋ฉด setUsername() ๋ฉ์๋๋ฅผ ์ฐพ์ ํธ์ถํ๋ฉด์ ๊ฐ์ ์ ๋ ฅ
HTTP message body
TEXT
HTTP Message Body Data ๋ฅผ InputStream ์ ์ฌ์ฉํด์ ์ง์ ์ฝ์ ์๋ ์์ง๋ง, Spring MVC๋ HttpEntity ์ง์
/** * HttpEntity: HTTP header, body ์ ๋ณด๋ฅผ ํธ๋ฆฌํ๊ฒ ์กฐํ ๋ฐ ์๋ต * - HttpMessageConverter ์ฌ์ฉ -> StringHttpMessageConverter ์ ์ฉ */ @PostMapping("/request-body-string") public HttpEntity<String> requestBodyString(HttpEntity<String> httpEntity) { String messageBody = httpEntity.getBody(); log.info("messageBody={}", messageBody); return new HttpEntity<>("ok"); }
HttpEntity๋ฅผ ์์๋ฐ์ RequestEntity, ResponseEntity
RequestEntity : HttpMethod, url ์ ๋ณด ๋ฑ ์ถ๊ฐ ์ ๋ณด ์ ๊ณต
ResponseEntity : HTTP ์ํ ์ฝ๋ ์ค์ ๊ฐ๋ฅ
return new ResponseEntity<String>("Hello World", responseHeaders, HttpStatus.CREATED)
@RequestBody ์ฌ์ฉ
header ๊ฐ ํ์ํ๋ค๋ฉด @RequestHeader
@ResponseBody @PostMapping("/request-body-string") public String requestBodyString(@RequestBody String messageBody) { log.info("messageBody={}", messageBody); return "ok"; }
JSON
@RequestBody
์๋ต ๋ถ๊ฐ๋ฅ(์๋ต ์ @ModelAttribute ์ ์ฉ)
HttpMessageConverter ์ฌ์ฉ -> MappingJackson2HttpMessageConverter
content-type: application/json
์๋ต์ ๊ฒฝ์ฐ์๋ @ResponseBody ๋ฅผ ์ฌ์ฉํ๋ฉด ํด๋น ๊ฐ์ฒด๋ฅผ HTTP ๋ฉ์์ง ๋ฐ๋์ ์ง์ ๋ฃ์ด์ค ์ ์์
@ResponseStatus(HttpStatus.OK) @ResponseBody @PostMapping("/request-body-json") public String requestBodyJson(@RequestBody HelloData data) { log.info("username={}, age={}", data.getUsername(), data.getAge()); return "ok"; }
@RequestBody ์์ฒญ : JSON ์์ฒญ -> HttpMessageConverter(JSON) -> ๊ฐ์ฒด
contenttype: application/json
@ResponseBody ์๋ต : ๊ฐ์ฒด -> HttpMessageConverter(JSON) -> JSON ์๋ต
Accept: application/json
HTTP Response
Spring Response Data ์์ฑ ๋ฐฉ๋ฒ
์ ์ ๋ฆฌ์์ค
HTML, css, js ์ ๊ณต
๊ธฐ๋ณธ ๊ฒฝ๋ก :
src/main/resources/static
Path :
src/main/resources/static/basic/hello-form.html
URI :
http://localhost:8080/basic/hello-form.html
View Template ์ฌ์ฉ
๋์ ์ธ HTML ์ ๊ณต
๊ธฐ๋ณธ ๊ฒฝ๋ก :
src/main/resources/templates
Path :
src/main/resources/templates/response/hello.html
@RequestMapping("/response-view") public String responseView(Model model) { model.addAttribute("data", "hello!!"); return "response/hello"; }
HTTP Message ์ฌ์ฉ
HTTP API - HTTP Message Body์ ๋ฐ์ดํฐ๋ฅผ ๋ด์ ์ ๊ณต
HTTP message body
TEXT
ResponseBody
@ResponseBody @GetMapping("/response-body-string") public String responseBody() { return "ok"; }
ResponseEntity
์๋ต์ฝ๋๋ฅผ ๋์ ์ผ๋ก ๋ณ๊ฒฝ ์ ์ฌ์ฉ
@GetMapping("/response-body-string") public ResponseEntity<String> responseBody() { return new ResponseEntity<>("ok", HttpStatus.OK); }
JSON
ResponseBody
@ResponseStatus(HttpStatus.OK) @ResponseBody @GetMapping("/response-body-json") public HelloData responseBodyJson() { HelloData helloData = new HelloData(); helloData.setUsername("userA"); helloData.setAge(20); return helloData; }
ResponseEntity
์๋ต์ฝ๋๋ฅผ ๋์ ์ผ๋ก ๋ณ๊ฒฝ ์ ์ฌ์ฉ
@GetMapping("/response-body-json") public ResponseEntity<HelloData> responseBodyJson() { HelloData helloData = new HelloData(); helloData.setUsername("userA"); helloData.setAge(20); return new ResponseEntity<>(helloData, HttpStatus.OK); }
HTTP Message Converter
HTTP Message Converter ์ ์ฉ ์๊ธฐ
HTTP ์์ฒญ: @RequestBody, HttpEntity(RequestEntity)
HTTP ์๋ต: @ResponseBody, HttpEntity(ResponseEntity)
Spring Boot Base Message Converter
0_ ByteArrayHttpMessageConverter
byte[] ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌ
ํด๋์ค ํ์ : byte[] , content-type: */*
์์ฒญ ex) @RequestBody byte[] data
์๋ต ex) @ResponseBody return byte[] ์ฐ๊ธฐ content-type application/octet-stream
1_ StringHttpMessageConverter
String ๋ฌธ์๋ก ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ค.
ํด๋์ค ํ์ : String , content-type: */*
์์ฒญ ex) @RequestBody String data
์๋ต ex) @ResponseBody return "ok" ์ฐ๊ธฐ content-type text/plain
2_ MappingJackson2HttpMessageConverter
application/json
ํด๋์ค ํ์ : ๊ฐ์ฒด ๋๋ HashMap, content-type: application/json ๊ด๋ จ
์์ฒญ ex) @RequestBody HelloData data
์๋ต ex) @ResponseBody return helloData ์ฐ๊ธฐ content-type application/json ๊ด๋ จ
Request Mapping Handler Adapter ๊ตฌ์กฐ
HTTP Message Converter ๋ RequestMappingHandlerAdapter -> ArgumentResolver, Handler -> ReturnValueHandler ์์ ์ฌ์ฉ๋์ด ํ์ํ ๊ฐ์ฒด๋ฅผ ์์ฑ
ArgumentResolver
ํ๋ผ๋ฏธํฐ๋ฅผ ์ ์ฐํ๊ฒ ์ฒ๋ฆฌ
์ ๋ ธํ ์ด์ ๊ธฐ๋ฐ ์ปจํธ๋กค๋ฌ๋ฅผ ์ฒ๋ฆฌํ๋ HandlerMethodArgumentResolver ๋ supportsParameter() ๋ฅผ ํธ์ถํด์ ํด๋น ํ๋ผ๋ฏธํฐ๋ฅผ ์ง์ํ๋์ง ์ฒดํฌ
์ง์ํ๋ฉด resolveArgument() ๋ฅผ ํธ์ถํด์ ํธ๋ค๋ฌ๊ฐ ํ์๋ก ํ๋ ๋ค์ํ ๊ฐ(๊ฐ์ฒด)์ ์์ฑ
์ด๋ ๊ฒ ์์ฑ๋ ๊ฐ์ฒด๊ฐ ํธ๋ค๋ฌ(์ปจํธ๋กค๋ฌ) ํธ์ถ ์ ๋์ด ๊ฐ
ReturnValueHandler
HandlerMethodReturnValueHandler ๋ ArgumentResolver ์ ๋น์ทํ ๋ฐฉ์์ผ๋ก ์๋ต๊ฐ์ ๋ณํ ๋ฐ ์ฒ๋ฆฌ
PRG (Post/Redirect/Get)
๋ฑ๋ก์ ์๋ฃํ๊ณ ์น ๋ธ๋ผ์ฐ์ ๋ฅผ ์๋ก๊ณ ์นจ ์ ์ค๋ณต ๋ฑ๋ก๋๋ ์ค๋ฅ ํด๊ฒฐ
์ํ ๋ฑ๋ก ํผ ์ด๋
์ํ ์ ์ฅ ๋ฐ ์ผํ ์์ธ ํ์ด์ง๋ก redirect
์ํ ์์ธํ์ด์ง ์ด๋
Last updated