[์คํ๋ง MVC] - 15. HTTP ์๋ต / HttpMessageConverter / ArgumentResolver
์คํ๋ง(์๋ฒ)์์ ์๋ต ๋ฐ์ดํฐ๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ
์ ์ ๋ฆฌ์์ค
์) ์น ๋ธ๋ผ์ฐ์ ์ ์ ์ ์ธ HTML, css, js๋ฅผ ์ ๊ณตํ ๋๋, ์ ์ ๋ฆฌ์์ค๋ฅผ ์ฌ์ฉํ๋ค.
๋ทฐ ํ ํ๋ฆฟ ์ฌ์ฉ
์) ์น ๋ธ๋ผ์ฐ์ ์ ๋์ ์ธ HTML์ ์ ๊ณตํ ๋๋ ๋ทฐ ํ
ํ๋ฆฟ์ ์ฌ์ฉํ๋ค.
HTTP ๋ฉ์์ง ์ฌ์ฉ
HTTP API๋ฅผ ์ ๊ณตํ๋ ๊ฒฝ์ฐ์๋ HTML์ด ์๋๋ผ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํด์ผ ํ๋ฏ๋ก,
HTTP ๋ฉ์์ง ๋ฐ๋์ JSON ๊ฐ์ ํ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ค์ด ๋ณด๋ธ๋ค.
HTTP ์๋ต - ์ ์ ๋ฆฌ์์ค, ๋ทฐ ํ
ํ๋ฆฟ
์ ์ ๋ฆฌ์์ค
์คํ๋ง ๋ถํธ๋ ํด๋์คํจ์ค์ ๋ค์ ๋๋ ํ ๋ฆฌ์ ์๋ ์ ์ ๋ฆฌ์์ค๋ฅผ ์ ๊ณตํ๋ค.
/static , /public , /resources , /META-INF/resources src/main/resources
๋ทฐ ํ ํ๋ฆฟ
๋ทฐ ํ ํ๋ฆฟ์ ๊ฑฐ์ณ์ HTML์ด ์์ฑ๋๊ณ , ๋ทฐ๊ฐ ์๋ต์ ๋ง๋ค์ด์ ์ ๋ฌํ๋ค.
๋ทฐ ํ ํ๋ฆฟ ๊ฒฝ๋ก : src/main/resources/templates
<p th:text="${data}">empty</p>
๋ ๋๋งํ ๋ ๋ชจ๋ธ์์ data ๋ผ๋ ํค์ ๊ฐ์ ๊บผ๋ด์ด empty ์นํ
๋ทฐ ํ ํ๋ฆฟ์ ํธ์ถ
ModelAndView
@RequestMapping("/response-view-v1")
public ModelAndView responseViewV1() {
ModelAndView mav = new ModelAndView("response/hello");
mav.addObject("data", "hello");
return mav;
}
๋ทฐ ๋ค์์ ์์ฑ์๋ก ์ ๋ฌ
์คํ๋ง์ด ์ ๊ณตํ๋ ModelAndView ๋ฅผ ํตํด Model ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ ๋๋ addObject() ๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
Model
@RequestMapping("/response-view-v2")
public String responseViewV2(Model model) {
model.addAttribute("data","hello!");
return "response/hello";
}
Model ์ ๋งค๊ฐ๋ณ์๋ก ์ ๋ฌ๋ฐ์
model.addAttribute("key" , "value") : ๋ฉ์๋๋ฅผ ์ด์ฉํ์ฌ view ์ ์ ๋ฌํ ๋ฐ์ดํฐ๋ฅผ key,value ์์ผ๋ก ์ ๋ฌํ๋ค
HTTP ์๋ต - HTTP API, ๋ฉ์์ง ๋ฐ๋์ ์ง์ ์ ๋ ฅ
@ResponseBody
@GetMapping("/response-body-string-v3")
public String responseBodyV3() {
return "OK";
}
@ResponseStatus(HttpStatus.OK)
@ResponseBody
@GetMapping("/response-body-json-v2")
public HelloData responseBodyJsonV2() {
HelloData helloData = new HelloData();
helloData.setUsername("userA");
helloData.setAge(20);
return helloData;
}
HTTP ๋ฉ์์ง ์ปจ๋ฒํฐ
@ResponseBody ์ฌ์ฉ ์๋ฆฌ

HTTP์ BODY์ ๋ฌธ์ ๋ด์ฉ์ ์ง์ ๋ฐํ
viewResolver ๋์ ์ HttpMessageConverter ๊ฐ ๋์
์คํ๋ง MVC๋ ๋ค์์ ๊ฒฝ์ฐ์ HTTP ๋ฉ์์ง ์ปจ๋ฒํฐ๋ฅผ ์ ์ฉํ๋ค.
- HTTP ์์ฒญ: @RequestBody , HttpEntity(RequestEntity)
- HTTP ์๋ต: @ResponseBody , HttpEntity(ResponseEntity)
๋์ ํด๋์ค ํ์ ๊ณผ ๋ฏธ๋์ด ํ์ ๋์ ์ฒดํฌํด์ ์ฌ์ฉ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํ๋ค.
๋ง์ฝ ๋ง์กฑํ์ง ์์ผ๋ฉด ๋ค์ ๋ฉ์์ง ์ปจ๋ฒํฐ๋ก ์ฐ์ ์์๊ฐ ๋์ด๊ฐ๋ค.

HTTP ์์ฒญ ๋ฐ์ดํฐ ์ฝ๊ธฐ
๋ฉ์์ง ์ปจ๋ฒํฐ๊ฐ ๋ฉ์์ง๋ฅผ ์ฝ์ ์ ์๋์ง ํ์ธํ๊ธฐ ์ํด canRead() ๋ฅผ ํธ์ถ
๋์ ํด๋์ค ํ์ ์ ์ง์ํ๋๊ฐ.
HTTP ์์ฒญ์ Content-Type ๋ฏธ๋์ด ํ์ ์ ์ง์ํ๋๊ฐ.
canRead() ์กฐ๊ฑด์ ๋ง์กฑํ๋ฉด read() ๋ฅผ ํธ์ถํด์ ๊ฐ์ฒด ์์ฑํ๊ณ , ๋ฐํํ๋ค.
content/type ์ ์๋ฒ๊ฐ ํด๋ผ์ด์ธํธ์ ์๋ตํ ๋ ๋ณด๋ด๋ ์ ๋ณด๋ก,
"์ด ๋ฆฌ์์ค๋ text/html ์ด์ผ. html ๋ก ํด์ํด์ค" ๋ผ๊ณ ์๋ฆฌ๋ ๊ฒ์ ๋๋ค.
HTTP ์๋ต ๋ฐ์ดํฐ ์์ฑ
๋ฉ์์ง ์ปจ๋ฒํฐ๊ฐ ๋ฉ์์ง๋ฅผ ์ธ ์ ์๋์ง ํ์ธํ๊ธฐ ์ํด canWrite() ๋ฅผ ํธ์ถํ๋ค.
๋์ ํด๋์ค ํ์ ์ ์ง์ํ๋๊ฐ.
HTTP ์์ฒญ์ Accept ๋ฏธ๋์ด ํ์ ์ ์ง์ํ๋๊ฐ
canWrite() ์กฐ๊ฑด์ ๋ง์กฑํ๋ฉด write() ๋ฅผ ํธ์ถํด์ HTTP ์๋ต ๋ฉ์์ง ๋ฐ๋์ ๋ฐ์ดํฐ๋ฅผ ์์ฑํ๋ค.
Accpet๋ ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์ ์์ฒญํ ๋ ๋ณด๋ด๋ ์ ๋ณด๋ก, ํด๋ผ์ด์ธํธ๊ฐ ํด์ํ ์ ์๋ ๋ฆฌ์์ค๊ฐ ๋ฌด์์ธ์ง๋ฅผ ์๋ฏธํฉ๋๋ค.
"๋๋ text/html, text/xml ์ ํด์ํ ์ ์์ด!" ํ๊ณ ์๋ฒ์๊ฒ ์๋ฆฝ๋๋ค.
์์ฒญ ๋งคํ ํจ๋ค๋ฌ ์ด๋ํฐ ๊ตฌ์กฐ
SpringMVC ๊ตฌ์กฐ

HTTP ๋ฉ์์ง ์ปจ๋ฒํฐ๋ ์คํ๋ง MVC ์ด๋์ฏค์์ ์ฌ์ฉ๋๋ ๊ฒ์ผ๊น?
๋ชจ๋ ๋น๋ฐ์ ์ ๋ ธํ ์ด์ ๊ธฐ๋ฐ์ ์ปจํธ๋กค๋ฌ, ๊ทธ๋ฌ๋๊น @RequestMapping ์ ์ฒ๋ฆฌํ๋ ํธ๋ค๋ฌ ์ด๋ํฐ์ธ
RequestMappingHandlerAdapter (์์ฒญ ๋งคํ ํจ๋ค๋ฌ ์ด๋ํฐ)์ ์๋ค.

RequestMapping ํธ๋ค๋ฌ ์ด๋ํฐ๊ฐ Argument Resolver ํํ
์ปจํธ๋กค๋ฌ(ํธ๋ค๋ฌ)๊ฐ ํ์๋ก ํ๋ ๋ค์ํ ํ๋ผ๋ฏธํฐ์ ๊ฐ(๊ฐ์ฒด)์ ๊ฐ์ ธ๋ค์ค ์ ์๋๊ณ ์์ฒญํ๋ค
Argument Resolver ๊ฐ ์์ฑํด์ค๋ค
๊ทธ๋ฆฌ๊ณ ์ด๋ ๊ฒ ํ๋ฆฌ๋ฏธํฐ์ ๊ฐ์ด ๋ชจ๋ ์ค๋น๋๋ฉด ์ปจํธ๋กค๋ฌ๋ฅผ ํธ์ถํ๋ฉด์ ๊ฐ์ ๋๊ฒจ์ค๋ค.
๋์ ๋ฐฉ์
ArgumentResolver ์ supportsParameter() ๋ฅผ ํธ์ถํด์ ํด๋น ํ๋ผ๋ฏธํฐ๋ฅผ ์ง์ํ๋์ง ์ฒดํฌํ๊ณ ,
์ง์ํ๋ฉด resolveArgument() ๋ฅผ ํธ์ถํด์ ์ค์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค.
๊ทธ๋ฆฌ๊ณ ์ด๋ ๊ฒ ์์ฑ๋ ๊ฐ์ฒด๊ฐ ์ปจํธ๋กค๋ฌ ํธ์ถ์ ๋์ด๊ฐ๋ ๊ฒ์ด๋ค.
ReturnValueHandler
ArgumentResolver ์ ๋น์ทํ๋ฐ, ์ด๊ฒ์ ์๋ต ๊ฐ์ ๋ณํํ๊ณ ์ฒ๋ฆฌํ๋ค.
HTTP ๋ฉ์์ง ์ปจ๋ฒํฐ ์์น

์์ฒญ์ ๊ฒฝ์ฐ @RequestBody ๋ฅผ ์ฒ๋ฆฌํ๋ ArgumentResolver ๊ฐ ์๊ณ , HttpEntity ๋ฅผ ์ฒ๋ฆฌํ๋ ArgumentResolver ๊ฐ ์๋ค.
์ด ArgumentResolver ๋ค์ด HTTP ๋ฉ์์ง ์ปจ๋ฒํฐ๋ฅผ ์ฌ์ฉํด์ ํ์ํ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๊ฒ์ด๋ค.
์๋ต์ ๊ฒฝ์ฐ @ResponseBody ์ HttpEntity ๋ฅผ ์ฒ๋ฆฌํ๋ ReturnValueHandler ๊ฐ ์๋ค.
๊ทธ๋ฆฌ๊ณ ์ฌ๊ธฐ์์ HTTP ๋ฉ์์ง ์ปจ๋ฒํฐ๋ฅผ ํธ์ถํด์ ์๋ต ๊ฒฐ๊ณผ๋ฅผ ๋ง๋ ๋ค.
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard
์คํ๋ง MVC 1ํธ - ๋ฐฑ์๋ ์น ๊ฐ๋ฐ ํต์ฌ ๊ธฐ์ - ์ธํ๋ฐ | ๊ฐ์
์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ ๋ ํ์ํ ๋ชจ๋ ์น ๊ธฐ์ ์ ๊ธฐ์ด๋ถํฐ ์ดํดํ๊ณ , ์์ฑํ ์ ์์ต๋๋ค. ์คํ๋ง MVC์ ํต์ฌ ์๋ฆฌ์ ๊ตฌ์กฐ๋ฅผ ์ดํดํ๊ณ , ๋ ๊น์ด์๋ ๋ฐฑ์๋ ๊ฐ๋ฐ์๋ก ์ฑ์ฅํ ์ ์์ต๋๋ค., -
www.inflearn.com