๐ก ๋ณธ ๊ฒ์๊ธ์ ๊น์ํ๋์ ์ธํ๋ฐ(Inflearn) ๊ฐ์ ์คํ๋ง ์
๋ฌธ - ์ฝ๋๋ก ๋ฐฐ์ฐ๋ ์คํ๋ง ๋ถํธ, ์น MVC, DB ์ ๊ทผ ๊ธฐ์ ์ ๋ํ ์๊ฐ ๊ธฐ๋ก์ฉ์ผ๋ก ์์ฑ๋์์ต๋๋ค.
1. ์ ์ ์ปจํ
์ธ
- ํ์ผ์ ์น ๋ธ๋ผ์ฐ์ ์ ๊ทธ๋๋ก ๋ด๋ ค์ฃผ๋ ๊ฒ์ ๋งํ๋ค.
- ์น ๋ธ๋ผ์ฐ์ ์์ hello-static.html์ ์์ฒญํ๋ฉด → ๋ด์ฅ ํฐ์บฃ ์๋ฒ์์ ์คํ๋ง ์ปจํ
์ด๋๋ก ์์ฒญ์ ๋๊ธฐ๊ฒ ๋๋ค. ์ด๋ "hello-static" ๊ด๋ จ ์ปจํธ๋กค๋ฌ(controller)๋ฅผ ์ฐพ์๋ณด๋ ๊ฒ์ด 1์์์ด๋, ์กด์ฌํ์ง ์์ ๊ฒฝ์ฐ resources/static ํด๋ ํ์์์ ํด๋น ํ์ผ์ ์ฐพ์ ์ ๋ฌํ๋ค.
2. MVC์ ํ
ํ๋ฆฟ ์์ง
2-1. ๋์ ์ปจํ
์ธ
- JSP, PHP์ ๊ฐ์ ํ
ํ๋ฆฟ ์์ง๋ค์ HTML์ ์๋ฒ์์ ํ๋ก๊ทธ๋๋ฐํด ๋์ ์ผ๋ก ๋ฐ๊ฟ ๋ด๋ ค์ฃผ๋ ์ญํ ์ ํ๋ค.
2-2. MVC
- ๋ชจ๋ธ(model), ๋ทฐ(view), ์ปจํธ๋กค๋ฌ(controller)๋ฅผ ์ผ์ปซ๋ MVC๋ ์์ฆ ๋ง์ด ์ฐ์ด๋ ๊ฐ๋ฐ ํจํด์ด๋ค.
- ๊ณผ๊ฑฐ์๋ ์ปจํธ๋กค๋ฌ(controller)์ ๋ทฐ(view)๋ฅผ ๊ตฌ๋ถ ์ง์ง ์๋ ํํ์ JSP ๊ธฐ๋ฐ์ผ๋ก MVC Model1 ๋ฐฉ์์ ์จ ์๋ค.
- MVC ํจํด์ ์๋ฒ์์ ๋ณํํด ๋ด๋ ค์ฃผ๋ ๋ฐฉ์์ด๋ผ๋ ์ ์์ ์ ์ ์ปจํ
์ธ ์๋ ์ฐจ์ด๊ฐ ์๋ค.
2-3. ํ์๋ฆฌํ(Thymeleaf)
- ํ์๋ฆฌํ(Thymeleaf)์ ์ฅ์ ์ผ๋ก ๊ผฝ์ ์ ์๋ ๊ฒ ์ค ํ๋๊ฐ ๋ฐ๋ก HTML ์์ฑ ํ ์ ๋๊ฒฝ๋ก(absolute path)๋ก ์ด์ด๋ณด๋ฉด ํด๋น ํ์ผ์ ๋ณด์ฌ์ค๋ค๋ ๊ฒ์ด๋ค.
- ์ฆ ์๋ฒ ๊ตฌ๋ ์์ด ์ด์ด๋ ๊ป๋ฐ๊ธฐ๋งํผ์ ํ์ธํ ์ ์๋๋ก ํด ์ค๋ค.
- ์ดํ ํ
ํ๋ฆฟ ์์ง์ผ๋ก์ ๋์ํ ๋๋ ๋ชจ๋ธ(model) ํตํด ๋์ด์จ ๊ฐ๋ค์ด ์นํ๋ผ ๋ณด์ฌ์ง๋ค.
<p th:text="'hello! ' + ${name}">hello! empty</p>
- ์๋ฅผ ๋ค์ด ์์ ๊ฐ์ ์์๊ฐ ์์ ๋, ์ ๋ ๊ฒฝ๋ก๋ก ๋ค์ด๊ฐ HTML ํ์ผ์ ์กฐํํ๊ฑฐ๋ ์ถ๋ ฅ๋ ๊ฒฐ๊ณผ๋ฌผ์ "hello! empty"๋ฟ์ด๋ฉฐ, ์์ค์์๋ ์๊ธฐ <p> ํ๊ทธ๊ฐ ๊ทธ๋๋ก ๋ด๊ฒจ์ ธ ์๋ ๋ชจ์ต์ ๋ณด์ธ๋ค.
- ์๋ฒ๋ฅผ ๊ตฌ๋์ํจ ํ ์ปจํธ๋กค๋ฌ(controller)์์ ๋ชจ๋ธ(model) ํตํด ${name} ์๋ฆฌ์ ์นํ๋ ๊ฐ์ "spring"์ผ๋ก ๋ช
์ํ๋ฉด, th:text= ์์ฑ์ด ๋์ํด → ํ๋ฌธ์ธ
"hello! empty"๋ ๊ฐ ๋ฐ ์์ด "hello! spring"์ด ๊ทธ ์๋ฆฌ์ ๋ฎ์ด์ฐ๊ธฐ๋ผ ๋ณด์ฌ์ง๋ค: model.addAttribute("name", "spring");
- ๋ค์ ๋งํด ํ์๋ฆฌํ(Thymeleaf)๋ ์๋ฒ ์ฌ์ด๋ ํ
ํ๋ฆฟ ์์ง(server-side template engine)์ผ๋ก์ ์๋ฒ๋ก๋ถํฐ ์ ๋ฌ๋ ๋ฐ๊ฐ ์์ด์ผ๋ง ์๋ง๊ฒ ๋์ํ๊ฒ ๋๋ค.
2-4. @RequestParam
- @RequestParam ์ด๋
ธํ
์ด์
์ ์์ฑ ์ค ํ๋์ธ required๋ ๊ธฐ๋ณธ๊ฐ์ด true์ด๋ค.
- ๋ฐ๋ผ์ ๋ํดํธ๋ก ์ค์ ๋ผ ์์ ๋๋ ํด๋น ํ๋ผ๋ฏธํฐ๋ฅผ ๋๊ฒจ์ค์ผ๋ง ์ปจํธ๋กค๋ฌ(controller)์ ๋งคํ์ด ์ด๋ค์ง๋ค.
- ์ ํ์ ์ผ๋ก ํ๋ผ๋ฏธํฐ๊ฐ ๋์ด์ฌ ๋๋ ์ด๋ฅผ false๋ก ๋ช
์ํด ์ฌ์ฉํ ์ ์๋ค.
3. API
3-1. API๋?
โ '์์ฆ์ API ๋ฐฉ์'์ด๋ผ๊ณ ์นญํ ์ ๋๋ก โ ๋ทฐ(Vue.js)๋ ๋ฆฌ์กํธ(React) ๋ฑ์ ์ฌ์ฉํจ์ ์์ด์๋ ๋ง์ด ์ฐ์ด๊ณ , โก์๋ฒ๊ฐ์ ์ด๋ค ๋ฐ์ดํฐ๊ฐ ํ๋ฅด๋์ง ํ์ธ์ฉ์ผ๋ก ์ฃผ๊ณ ๋ฐ๋ ๊ณผ์ ์์๋ ์ด ๊ฐ์ ๋ฐฉ๋ฒ์ ์ด๋ค. API ๋ฐฉ์์ ์ผ์ปฌ์ด ์๋ฐ๋น(JavaBeans) ํ์ค ๋ฐฉ์, ํ๋กํผํฐ(Property) ์ ๊ทผ ๋ฐฉ์์ด๋ผ๊ณ ๋ ๋ถ๋ฅธ๋ค.
- JSON์ด๋ผ๋ ๋ฐ์ดํฐ ํฌ๋งท์ผ๋ก ํด๋ผ์ด์ธํธ์๊ฒ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๋ฐฉ์์ ๋งํ๋ค.
- JSON์ ํค(key)-๊ฐ(value) ํ ์์ผ๋ก ์ด๋ค์ ธ ์๋ค.
- ๊ณผ๊ฑฐ์๋ XML ๋ฐฉ์์ ์ผ์ผ๋, ์ต๊ทผ์๋ ๊ฑฐ์ JSON ๋ฐฉ์์ผ๋ก ํต์ผ๋๋ค๊ณ ๋ณผ ์ ์๋ค.
- ์๋ฒ ์ฌ์ด๋ ํ
ํ๋ฆฟ์ ์ธ ๋๋ HTML์ ๋ฐฑ๋จ(back)์์ ์ง์ ์กฐ์ํ๋ ๋ฐ๋ฉด, API๋ฅผ ํตํด์๋ ๋ฐ์ดํฐ๋ง ๋ด๋ ค์ฃผ๊ณ ํ๋ก ํธ๋จ(front)์์ ์ด๋ฅผ ์ฒ๋ฆฌํ๊ฒ๋ ํ๋ค๋ ์ ์์ ์ฐจ์ด๊ฐ ์๋ค.
3-2. @ResponseBody
- @ResponseBody๋ผ๊ณ ๋ช
์๋ผ ์๋ค๋ฉด ์คํ๋ง(Spring) ์ฐจ์์์ ๊ธฐ๋ณธ์ ์ผ๋ก JSON ํ์
์ผ๋ก ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํด์ค๋ค.
- @ResponseBody ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํ๊ฑฐ๋ HttpMessage์ ๋ฐ๋(body) ๋ถ๋ถ์์ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๊ฒ ๋๋ค.
- ์ฆ
๊ธฐํ ๋ฆฌ์กธ๋ฒ(resolver)๋ค์ ๊ฑฐ์น์ง ์๊ณ , ๊ฒฐ๊ณผ๊ฐ์ ๊ณง๋ฐ๋ก ์ ๋ฌ์ฉ ๋ฉ์์ง์ ๋ด๋ ๊ฒ์ ์๋ฏธํ๋ค.
- ์ด๋ ๊ฒ JSON ํฌ๋งท์ผ๋ก ์ ๋ฌ๋ ๋ฐ์ดํฐ์ ๋ํ ์ฒ๋ฆฌ๋ ํ๋ก ํธ๋จ(front)์์ ๋งก๋๋ค.
@Controller
public class HelloController {
@GetMapping("hello-api")
@ResponseBody
public Hello helloApi(@RequestParam("name") String name) {
Hello hello = new Hello();
hello.setName(name);
return hello;
}
static class Hello {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
{"name":"spring"}
- ๋ฐํ๊ฐ์ ์ผ๋ฐ ๋ฌธ์์ด(String) ์๋ ํด๋์ค(class) ํ์
๋ฑ์ ๋ ํผ๋ฐ์ค๋ก ๋๊ฒจ์ผ ํ๋ ๊ฒฝ์ฐ์๋ ๊ฒํฐ(getter)/์ธํฐ(setter) ๊ธฐ๋ฐ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์นํํด ๋ณด๋ผ ์๊ฐ ์๋ค.
- ์ด๋๋ ๋ง์ฐฌ๊ฐ์ง๋ก {๋ณ์๋ช
:๊ฐ} ํํ๋ก ๋ฆฌํด๋๋ค.
3-3. API ๋์ ๊ณผ์
โ ๊ฐ์ฒด๋ฅผ JSON์ผ๋ก ๋ฐ๊ฟ์ฃผ๋ ๋ ๊ฐ์ง ์ ๋ช
ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก๋ ์ญ์จ(Jackson)๊ณผ ์ง์จ(gson)์ด ์๋ค. ์คํ๋ง(Spring)์ ์ญ์จ(Jackson)์ ๊ธฐ๋ณธ ํ์ฌํ๊ณ ์์ผ๋ฉฐ, ์ด๋ ์ฆ ๊ทธ๋งํผ ๋ฒ์ฉ์ฑ์ด ์๊ณ ์ด๋ฏธ ๊ฒ์ฆ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ๋งํ๋ค. ๋ฌผ๋ก ํ์์ ๋ฐ๋ผ ์ง์จ(gson) ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ถ๊ฐํด ์ฌ์ฉํ ์๋ ์๋ค.
- โ ์น ๋ธ๋ผ์ฐ์ ์์ ์์ฒญ์ด ์๊ธฐ๋ฉด → ํฐ์บฃ(Tomcat) ๋ด์ฅ ์๋ฒ์์๋ ์ด๋ฅผ → ์คํ๋ง(Spring)์๊ฒ ๋์ง๋ค.
- โก@ResponseBody ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํ๋ ์ด ๊ณผ์ ์์
๋ทฐ ๋ฆฌ์กธ๋ฒ(View Resolver) ๋์ ๋์ํ๋ ๊ฒ์ด HttpMessageConverter์ด๋ค.
- ์๋๋ ๋ทฐ ๋ฆฌ์กธ๋ฒ(View Resolver)์๊ฒ ๋์ ธ์์ง๋ง, @ResponseBody ์ด๋
ธํ
์ด์
์ด ๋ถ์ด์๊ณ ๊ฐ์ฒด๊ฐ ์๋ฆฌํ๋ฉด ์คํ๋ง์ ๊ธฐ๋ณธ์ ์ผ๋ก JSON ํฌ๋งท์ ๋ง๋ค์ด์ ์๋ต์ ๋ฐํํ๋๋ก ์ค์ ๋ผ ์๋ค.
- ๋จ์ ๋ฌธ์์ธ ๊ฒฝ์ฐ StringHttpMessageConverter(StringConverter)๊ฐ ์ฒ๋ฆฌํ๋ค.
- ๊ธฐ๋ณธ ๊ฐ์ฒด์ผ ๋๋ MappingJackson2HttpMessageConverter(JsonConverter)๊ฐ ๋์ํ๋ค.
- ๋ฐ์ดํธ(byte) ์ฒ๋ฆฌ ๋ฑ ๊ทธ ์ธ ์ฌ๋ฌ HttpMessageConverter๊ฐ ๊ธฐ๋ณธ ๋ฑ๋ก๋ผ ์์ผ๋ฉฐ, ํด๋ผ์ด์ธํธ์ HTTP Accept ํค๋ ๋ฐ ์๋ฒ์ ์ปจํธ๋กค๋ฌ ๋ฐํ ํ์
์ ๋ณด๋ฅผ ์กฐํฉํด HttpMessageConverter๊ฐ ์ ํ๋๋ค.
- โข์น ๋ธ๋ผ์ฐ์ /์๋๋ก์ด๋ ํด๋ผ์ด์ธํธ/๋ค๋ฅธ ์๋ฒ ๋ฑ ์์ฒญํ ๋์์๊ฒ ๊ฒฐ๊ณผ๊ฐ์ ๋๊ฒจ์ค๋ค.
- @ResponseBody ์ด๋
ธํ
์ด์
์ด ์ ์ฉ๋์ผ๋ฏ๋ก HTTP ๋ฐ๋(body)์ ๋ฌธ์ ๋ด์ฉ์ ์ง์ ๋ฐํํ ๊ฒ์ด๋ค.