
์ง๊ธ ๋ฐ๋ก ์ดํดํ์, ํด๋ผ์ด์ธํธ ์์ฒญ์์ ์๋ต๊น์ง์ ์ ๊ณผ์ ์ ํ๋์!
ํด๋ผ์ด์ธํธ: ์ฌ์ฉ์๊ฐ ๋ธ๋ผ์ฐ์ ์์ HTTP ์์ฒญ์ ๋ณด๋ด๋ฉด, ์ด ์์ฒญ์ ์๋ฒ๋ก ์ ๋ฌ๋๊ณ DispatcherServlet์์ ๋ณธ๊ฒฉ์ ์ธ ์ฒ๋ฆฌ๊ฐ ์์๋ฉ๋๋ค.
DispatcherServlet์ Spring MVC์ ํต์ฌ! ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ์ฒ๋ฆฌํ๊ธฐ ์ํ ์ค์ ํ๋ธ ์ญํ ์ ํ๋ฉฐ, ์์ฒญ์ ์ ์ ํ ์ปจํธ๋กค๋ฌ๋ก ๋ผ์ฐํ ํ๊ฑฐ๋ ๋ทฐ(View)๋ฅผ ์ ํํฉ๋๋ค.
DefaultAnnotationHandlerMapping: ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ์ฒ๋ฆฌํ ์ปจํธ๋กค๋ฌ๋ฅผ ์ฐพ์์ฃผ๋ ์ญํ ์ ๋ด๋นํฉ๋๋ค. @Controller์ @RequestMapping ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํด ์์ฒญ์ ๋งคํํฉ๋๋ค.
Tip: Spring 3.0 ์ด์ ์๋ ์ด ์์
์ ์๋์ผ๋ก ํ์ง๋ง, ์ด์ ๋ ์๋์ผ๋ก ์ค์ ๋๋ ํธ๋ฆฌํด์ก์ฃ ! ๐
Controller: ์ฌ๊ธฐ์ ๋ชจ๋ ๋ง๋ฒ์ด ์ผ์ด๋ฉ๋๋ค! ๐ซ @Controller์ @RequestMapping์ ์ฌ์ฉํด ํน์ URL์ ๋ง๋ ๋ฉ์๋๋ฅผ ์ฒ๋ฆฌํ๊ณ , ์์ฒญ์ ๋ง๋ ๋น์ฆ๋์ค ๋ก์ง์ ์ํํฉ๋๋ค. ๊ฒฐ๊ณผ๋ ๋ทฐ(View)๋ก ์ ๋ฌ๋๊ฑฐ๋, ๋ค๋ฅธ ์ฒ๋ฆฌ๊ฐ ์ด๋ฃจ์ด์ง์ฃ !
@Controller์ @RequestMapping ์์ ํด๋ถ ๐ํด๋ผ์ด์ธํธ ์์ฒญ์ ์ฒ๋ฆฌํ๋ ์ด ๋ชจ๋ ๊ณผ์ , ์๊ณ ๋๋ฉด ๋ ์ฌ์์ง๋ค!
@Controller ์ด๋
ธํ
์ด์
- ์ปจํธ๋กค๋ฌ์ ํต์ฌ!@Controller๋ ์ด ํด๋์ค๊ฐ Spring MVC ์ปจํธ๋กค๋ฌ ์ญํ ์ ํ๋ค๋ ๊ฒ์ ์๋ ค์ค๋๋ค. ๐@RequestMapping("/article") - ๊ฒฝ๋ก ์ค์ ์ ์์!"/article"๋ก ์์ํ๋ ๋ชจ๋ ์์ฒญ์ ์ด ์ปจํธ๋กค๋ฌ๊ฐ ๋งก๊ฒ ๋ค๋ ๋ป์
๋๋ค! @RequestMapping, @GetMapping, @PostMapping ๋ฑ์ผ๋ก ๊ตฌ์ฒดํ๋ฉ๋๋ค. ๐ค๏ธpublic BoardController(BoardService boardService) {
this.boardService = boardService;
}
BoardService๋ฅผ ์ฃผ์
๋ฐ์ ์์กด์ฑ์ ๊ด๋ฆฌํฉ๋๋ค.@GetMapping("/write") - GET ์์ฒญ์ ์ฒ๋ฆฌ!@GetMapping์ HTTP GET ์์ฒญ์ ์ฒ๋ฆฌํ๋ ๋ฉ์๋๋ฅผ ์ง์ ํฉ๋๋ค./article/write๋ก ๋ค์ด์ค๋ GET ์์ฒญ์ ์ด ๋ฉ์๋๊ฐ ์ฒ๋ฆฌํ๋ฉฐ, ์ฌ์ฉ์๊ฐ ๊ธ์ ์์ฑํ๋ ํ์ด์ง๋ก ์ด๋ํ ๋ ํธ์ถ๋ฉ๋๋ค. ๐ @RequestParam์ ์ฌ์ฉํด ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ฐ์๋ค์
๋๋ค. ์ด ์์์์๋ ์ฌ๋ฌ ํ๋ผ๋ฏธํฐ๋ฅผ Map<String, String>์ผ๋ก ์ฒ๋ฆฌํ๊ณ ์์ต๋๋ค.Model ๊ฐ์ฒด - ๋ทฐ๋ก ๋ฐ์ดํฐ ์ ๋ฌํ๊ธฐ!Model ๊ฐ์ฒด!model.addAttribute()๋ฅผ ์ฌ์ฉํด ๋ฐ์ดํฐ๋ฅผ ๋ด๊ณ , ๋ทฐ์์ ์ด๋ฅผ ํ์ฉํ์ฌ ์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ค๋๋ค. ๐ก์ผ๋ฐ์ ์ธ ์ฝ๋๋ก ๋ ์ฝ๊ฒ ์ดํดํด๋ณผ๊น์?
@Controller
@RequestMapping("/article")
public class ArticleController {
private final ArticleService articleService;
public ArticleController(ArticleService articleService) {
this.articleService = articleService;
}
@GetMapping("/write")
public String writeArticle(@RequestParam Map<String, String> params, Model model) {
model.addAttribute("page", params.get("page"));
model.addAttribute("title", params.get("title"));
model.addAttribute("content", params.get("content"));
return "article/write";
}
}
@Controller์ @RequestMapping("/article")์ ์ฌ์ฉํด /article ๊ฒฝ๋ก์ ์์ฒญ์ ์ฒ๋ฆฌํฉ๋๋ค. writeArticle ๋ฉ์๋๋ /article/write ๊ฒฝ๋ก๋ก ๋ค์ด์ค๋ GET ์์ฒญ์ ์ฒ๋ฆฌํ๊ณ , ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ฐ์ Model ๊ฐ์ฒด๋ก ๋ฐ์ดํฐ๋ฅผ ๋ทฐ์ ์ ๋ฌํฉ๋๋ค. ์ง๊ธ ๋น์ฅ ๋ฐฐ์๋ณด๋ Spring ์ปจํธ๋กค๋ฌ ๋ฑ๋ก ๋ฐฉ๋ฒ์ ๋ชจ๋ ๊ฒ!
์ค๋ช : Spring์์ ์ปจํธ๋กค๋ฌ ํด๋์ค๋ฅผ XML ํ์ผ์ ํตํด ์๋์ผ๋ก ๋ฑ๋กํ ์ ์์ต๋๋ค. ์ด ๋ฐฉ์์ ์ปจํธ๋กค๋ฌ๋ฅผ ๋น(bean)์ผ๋ก ์ง์ ๋ฑ๋กํ๊ณ , ๊ทธ ํด๋์ค๊ฐ ์์กดํ๋ ๊ฐ์ฒด๋ค์ ์์ฑ์๋ ํ๋์ ์ฃผ์ ํ ์ ์๊ฒ ํด์ค๋๋ค. ๐ฏ
์์ ์ฝ๋:
<bean class="com.example.web.controller.MyController">
<constructor-arg ref="myService" />
</bean>
class="com.example.web.controller.MyController": Spring ์ปจํ
์ด๋์ MyController๋ฅผ ๋น์ผ๋ก ๋ฑ๋ก!<constructor-arg ref="myService" />: ์ปจํธ๋กค๋ฌ์ ํ์ํ ์์กด์ฑ ์๋น์ค๋ ๊ฐ์ด ์ฃผ์
!์ค๋ช : Spring์์ XML ํ์ผ์ ํตํด ์ด๋ ธํ ์ด์ ์ด ๋ฌ๋ฆฐ ์ปจํธ๋กค๋ฌ๋ค์ ์๋ ์ค์บํ์ฌ ๋น์ผ๋ก ๋ฑ๋กํ๋ ๋ฐฉ์์ ๋๋ค. ๐ก ์ผ์ผ์ด ์๋ ๋ฑ๋กํ์ง ์์๋ Spring์ด ์์์ ์ฒ๋ฆฌํฉ๋๋ค!
์์ ์ฝ๋:
<context:component-scan base-package="com.example.web.controller" />
base-package="com.example.web.controller": ์ด ๊ฒฝ๋ก ๋ด์์ @Controller ์ด๋
ธํ
์ด์
์ด ๋ถ์ ํด๋์ค๋ฅผ ์๋์ผ๋ก ์ค์บํ์ฌ ๋น์ผ๋ก ๋ฑ๋ก!@Controller ์ด๋
ธํ
์ด์
์ด ๋ถ์ ํด๋์ค๋ฅผ ์๋์ผ๋ก ๋ฑ๋กํ๋ ๋ฐฉ์์ผ๋ก, ํธ๋ฆฌํจ๊ณผ ์ ์ง๋ณด์์ฑ์ด ๋์. ๐ผ๐ก Tip: Spring 3.0 ์ดํ๋ก๋ ์๋ ์ค์บ์ด ํจ์ฌ ๋ณดํธ์ ์ด๊ณ , ์๋ ๋ฑ๋ก๋ณด๋ค๋ ๋ ๋ง์ด ์ฌ์ฉ๋๊ณ ์์ต๋๋ค!
@RequestMapping๊ณผ HTTP ๋ฉ์๋์ ์๋ฒฝ ๋งคํ ๋น๋ฒ! ๐URL๊ณผ ๋ฉ์๋ ๋งคํ์ ๋ชจ๋ ๊ฒ, ์ด์ ํ์คํ๊ฒ ๋ง์คํฐํ์!
@RequestMapping ์ด๋
ธํ
์ด์
- URL ๋งคํ์ ํต์ฌ!@RequestMapping์ ์์ฒญ URL๊ณผ HTTP ๋ฉ์๋๋ฅผ ๋งคํํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. ๐ฏ@RequestMapping - ๊ธฐ๋ณธ ๊ฒฝ๋ก ์ค์ @RequestMapping("/article")๊ณผ ๊ฐ์ด ์ ์ธํ๋ฉด, ์ด ํด๋์ค ๋ด ๋ชจ๋ ๋ฉ์๋๋ ๊ธฐ๋ณธ์ ์ผ๋ก /article ๊ฒฝ๋ก์ ๋ํ ์์ฒญ์ ์ฒ๋ฆฌํฉ๋๋ค.@Controller
@RequestMapping("/article")
public class ArticleController {
private final Logger logger = LoggerFactory.getLogger(ArticleController.class);
@GetMapping("/write")
public String writeForm(Model model) {
logger.debug("Rendering write form");
model.addAttribute("formTitle", "Write an Article");
return "article/write";
}
@PostMapping("/write")
public String submitArticle(@ModelAttribute ArticleDto articleDto) {
logger.debug("Article submitted: {}", articleDto);
// ๋น์ฆ๋์ค ๋ก์ง ์ฒ๋ฆฌ ํ, ๋ทฐ๋ฅผ ๋ฆฌํด
return "redirect:/article/success";
}
}
@RequestMapping("/article"): ํด๋์ค ๋ ๋ฒจ์์ ๊ฒฝ๋ก๋ฅผ ์ง์ ํ์ฌ ์ด ํด๋์ค์ ๋ชจ๋ ๋ฉ์๋๊ฐ /article ๊ฒฝ๋ก๋ฅผ ๊ธฐ๋ณธ์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค.@GetMapping("/write"): /article/write ๊ฒฝ๋ก๋ก ๋ค์ด์ค๋ GET ์์ฒญ์ ์ฒ๋ฆฌํฉ๋๋ค. ๋ณดํต ์ฌ์ฉ์๊ฐ ์์ฑํ ์
๋ ฅ ํผ์ ๋ ๋๋งํ ๋ ์ฌ์ฉ๋ฉ๋๋ค. ๐@PostMapping("/write"): ๊ฐ์ ๊ฒฝ๋ก์ ๋ํ POST ์์ฒญ์ ์ฒ๋ฆฌํฉ๋๋ค. ์ฌ์ฉ์๊ฐ ์์ฑํ ๋ฐ์ดํฐ๋ฅผ ์๋ฒ๋ก ์ ์กํ ๋ ์ฌ์ฉ๋์ฃ ! ๐@GetMapping์ GET ์์ฒญ์๋ง ๋ฐ์ํ๋ฉฐ, ์ฃผ๋ก ๋ฐ์ดํฐ ์กฐํ๋ ํผ ๋ ๋๋ง ์ ์ฌ์ฉ๋ฉ๋๋ค. @PostMapping์ POST ์์ฒญ์๋ง ๋ฐ์ํ๋ฉฐ, ์๋ฒ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์ถํ ๋ ์ฌ์ฉ๋ฉ๋๋ค.์์ ์ฝ๋๋ /article/write ๊ฒฝ๋ก์ ๋ํ GET๊ณผ POST ์์ฒญ์ ๊ฐ๊ฐ ๋ค๋ฅด๊ฒ ์ฒ๋ฆฌํฉ๋๋ค.
์์ฒญ ์ ๋ณด, ์ฟ ํค, ์ธ์ ๊น์ง ํ ๋ฒ์ ๋ค๋ฃจ๋ ๋น๋ฒ!
HttpServletRequest, HttpServletResponse, HttpSessionServlet API ๊ฐ์ฒด ์ง์ ์ฌ์ฉ ๊ฐ๋ฅ!
HttpServletRequest: ํด๋ผ์ด์ธํธ ์์ฒญ ์ ๋ณด๋ฅผ ๋ด์ ๊ฐ์ฒด๋ก, ํ๋ผ๋ฏธํฐ, ํค๋, ์ธ์
์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. HttpServletResponse: ์๋ฒ๊ฐ ํด๋ผ์ด์ธํธ๋ก ์๋ต์ ๋ณด๋ผ ๋ ์ฌ์ฉํฉ๋๋ค. ์ํ ์ฝ๋ ์ค์ , ์๋ต ๋ฐ์ดํฐ ์ ์ก ๋ฑ ๋ค์ํ ์ฉ๋๋ก ์ฐ์
๋๋ค! HttpSession: ์ฌ์ฉ์ ์ธ์
๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ฑฐ๋ ๋ถ๋ฌ์ฌ ๋ ์ฌ์ฉํฉ๋๋ค. ๐ ๏ธLocale - ๋ค๊ตญ์ด ์ฒ๋ฆฌ์ ํ์!Locale: ํ์ฌ ์์ฒญ์ ๋ก์ผ์ผ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๋ฉฐ, ๋ค๊ตญ์ด ์ฒ๋ฆฌ ๋ฑ์ ์ ์ฉํฉ๋๋ค. ์ฌ์ฉ์์ ์ธ์ด ์ค์ ์ ๋ฐ๋ผ ๋ง์ถค ์๋ต์ ์ ๊ณตํ ์ ์์ต๋๋ค! ๐ฃ๏ธ
InputStream, Reader - ์คํธ๋ฆผ์ผ๋ก ์์ฒญ ๋ฐ์ดํฐ ์ฝ๊ธฐ์คํธ๋ฆผ์ ํตํด ์์ฒญ ๋ฐ์ดํฐ๋ฅผ ์ง์ ์ฝ์ ์ ์์ต๋๋ค. ์ฃผ๋ก ํ์ผ ์ ๋ก๋๋ ๋์ฉ๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์์ ๋ง์ด ์ฌ์ฉ๋ฉ๋๋ค. ๐พ
OutputStream, Writer - ์๋ต ๋ฐ์ดํฐ ์์ฑํ๊ธฐ์๋ฒ๊ฐ ํด๋ผ์ด์ธํธ๋ก ์๋ตํ ๋ ๋ฐ์ดํฐ๋ฅผ ์คํธ๋ฆผ์ผ๋ก ์์ฑํ ์ ์์ต๋๋ค. ํ์ผ ๋ค์ด๋ก๋๋ ๋ฐ์ด๋๋ฆฌ ๋ฐ์ดํฐ ์ ์ก์ ์์ฃผ ์ฌ์ฉ๋ฉ๋๋ค! ๐
@PathVariable - URI ํ
ํ๋ฆฟ ๋ณ์ ๋ฐ๊ธฐ@PathVariable: URI ํ
ํ๋ฆฟ์์ ๋ณ์๋ฅผ ๊ฐ์ ธ์ฌ ๋ ์ฌ์ฉ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด, /articles/{id} ๊ฒฝ๋ก์์ {id} ๊ฐ์ ๋ฐ์์ฌ ์ ์์ต๋๋ค.
@GetMapping("/articles/{id}")
public String getArticle(@PathVariable("id") Long articleId) {
// articleId ์ฌ์ฉ
}
@RequestParam - ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ ์ฒ๋ฆฌ@RequestParam: ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ฐ์์ฌ ๋ ์ฌ์ฉ๋ฉ๋๋ค. ?name=value ํํ์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐ ์์ฃผ ์ฐ์ด์ฃ ! ๐ก
@GetMapping("/search")
public String search(@RequestParam("query") String query) {
// query ์ฌ์ฉ
}
@RequestHeader - ์์ฒญ ํค๋ ์ ๋ณด ๊ฐ์ ธ์ค๊ธฐ@RequestHeader: HTTP ์์ฒญ ํค๋ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ฌ ๋ ์ฌ์ฉ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด, User-Agent ํค๋ ์ ๋ณด๋ฅผ ์ป์ ์ ์์ต๋๋ค!
@GetMapping("/header")
public String getHeader(@RequestHeader("User-Agent") String userAgent) {
// User-Agent ์ฌ์ฉ
}
@CookieValue - ์ฟ ํค ๊ฐ ์ฒ๋ฆฌํ๊ธฐ@CookieValue: HTTP ์์ฒญ์ ํฌํจ๋ ์ฟ ํค ๊ฐ์ ๊ฐ์ ธ์ต๋๋ค! ๐ช
@GetMapping("/cookie")
public String getCookie(@CookieValue("sessionId") String sessionId) {
// sessionId ์ฌ์ฉ
}
@RequestBody - ๋ฐ๋ ๋ฐ์ดํฐ ๊ฐ์ฒด๋ก ๋ณํ@RequestBody: HTTP ์์ฒญ์ Body ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฒด๋ก ๋ณํํ์ฌ ๋ฐ์ ๋ ์ฌ์ฉ๋ฉ๋๋ค. ์ฃผ๋ก JSON ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ ๋ ์ฌ์ฉ๋ฉ๋๋ค! ๐งโ๐ป
@PostMapping("/submit")
public String submitData(@RequestBody DataDto data) {
// data ๊ฐ์ฒด ์ฌ์ฉ
}
Map, Model, ModelMap - ๋ทฐ๋ก ๋ฐ์ดํฐ ์ ๋ฌModel ๊ฐ์ฒด๋ ์ปจํธ๋กค๋ฌ์์ ๋ทฐ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ์ญํ ์ ํฉ๋๋ค. ๋ฐ์ดํฐ๋ฅผ ๋ทฐ์์ ๋ ๋๋งํ ์ ์๊ฒ ํด์ฃผ์ฃ !
@GetMapping("/view")
public String viewData(Model model) {
model.addAttribute("key", "value");
return "viewName";
}
DTO ๊ฐ์ฒด๋ก ํผ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ฒ ๋ฐ์ ์ ์์ต๋๋ค. ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ ๋ฐ์ดํฐ๋ฅผ ๊น๋ํ๊ฒ ๋งคํํ๋ ๋ฐฉ์์ ๋๋ค! ๐ฏ
@PostMapping("/submit")
public String submitForm(@ModelAttribute FormDto form) {
// form ๊ฐ์ฒด ์ฌ์ฉ
}
Errors, BindingResult - ์ ํจ์ฑ ๊ฒ์ฆ ๊ฒฐ๊ณผ ์ฒ๋ฆฌ์ ํจ์ฑ ๊ฒ์ฆ ์คํจ ์, BindingResult๋ฅผ ํตํด ์ค๋ฅ ํญ๋ชฉ์ ํ์ธํ๊ณ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ๐ก๏ธ
@PostMapping("/submit")
public String submitForm(@ModelAttribute FormDto form, BindingResult result) {
if (result.hasErrors()) {
return "formPage";
}
// ์ ํจ์ฑ ๊ฒ์ฌ ํต๊ณผ
}
SessionStatus - ์ธ์
์ด๊ธฐํSessionStatus: ์ธ์
์์ฑ์ ์ด๊ธฐํํ๊ฑฐ๋ ์๋ฃํ ๋ ์ฌ์ฉ๋ฉ๋๋ค. ๋ช
์์ ์ผ๋ก ์ธ์
์ ๋๋ด๊ณ ์ถ์ ๋ ์ ์ฉํฉ๋๋ค!
@RequestParam ์์ ์ ๋ณต! ํ๋ผ๋ฏธํฐ ๋งคํ์ ๋ชจ๋ ๊ฒ ๐ํผ ๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ถํฐ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๊น์ง! Spring MVC์์ ํ๋ผ๋ฏธํฐ ๋ค๋ฃจ๊ธฐ, ์ด์ ์ฝ๊ฒ ๋ฐฐ์ฐ์!
@RequestParam ์ด๋
ธํ
์ด์
- ํ๋ผ๋ฏธํฐ๋ฅผ ์์ฝ๊ฒ ๋งคํํ์!@RequestParam์ HTTP ์์ฒญ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ฉ์๋ ํ๋ผ๋ฏธํฐ๋ก ๋งคํํ๋ ๊ฐ๋ ฅํ ๋๊ตฌ์
๋๋ค.value: ์์ฒญ ํ๋ผ๋ฏธํฐ ์ด๋ฆ์ ์ง์ ํฉ๋๋ค.defaultValue: ํ๋ผ๋ฏธํฐ๊ฐ ์กด์ฌํ์ง ์์ ๊ฒฝ์ฐ ๊ธฐ๋ณธ๊ฐ์ ์ง์ ํ ์ ์์ต๋๋ค.required: ํ๋ผ๋ฏธํฐ๊ฐ ํ์์ธ์ง ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํฉ๋๋ค. ๊ธฐ๋ณธ๊ฐ์ true๋ก ํ์์ด์ง๋ง, false๋ก ์ค์ ํ๋ฉด ์์ด๋ ์๋ฌ๊ฐ ๋ฐ์ํ์ง ์์์! ๐์๋ ์ฝ๋๋ ํผ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค! ๐ฏ
@PostMapping("/submit")
public String handleForm(
@RequestParam("name") String userName,
@RequestParam(value = "age", defaultValue = "25") int userAge,
@RequestParam(value = "hobbies", required = false) String[] hobbies,
Model model) {
// ์ฝ์์ ์
๋ ฅ๋ ๊ฐ ์ถ๋ ฅ
System.out.println("Name: " + userName + ", Age: " + userAge);
if (hobbies != null) {
System.out.println("Hobbies: " + Arrays.toString(hobbies));
}
// ๋ชจ๋ธ์ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ์ฌ ๋ทฐ์ ์ ๋ฌ
model.addAttribute("userName", userName);
model.addAttribute("userAge", userAge);
model.addAttribute("hobbies", hobbies != null ? Arrays.toString(hobbies) : "No hobbies selected");
return "formResult"; // ๊ฒฐ๊ณผ ํ์ด์ง๋ก ์ด๋
}
@RequestParam("name"): ํ์ ํ๋ผ๋ฏธํฐ์ธ "name" ๊ฐ์ ๋ฐ์ userName ๋ณ์์ ์ ์ฅํฉ๋๋ค. @RequestParam(value = "age", defaultValue = "25"): ํ๋ผ๋ฏธํฐ๊ฐ ์์ ๊ฒฝ์ฐ, ๊ธฐ๋ณธ๊ฐ์ผ๋ก 25๋ฅผ ์ค์ ํฉ๋๋ค! ๐ @RequestParam(value = "hobbies", required = false): ์ทจ๋ฏธ ๊ฐ์ ์ ํ ์ฌํญ! null ํ์ฉ์ผ๋ก, ์
๋ ฅํ์ง ์์๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง ์์์. ๐กURL: /submit?name=John&age=30&hobbies=reading,traveling
John, ๋์ด๋ 30, ์ทจ๋ฏธ๋ reading๊ณผ traveling์ด ์ ๋ฌ๋ฉ๋๋ค. ๐โ๏ธURL: /submit?name=Jane
Jane, ๋์ด๋ ๊ธฐ๋ณธ๊ฐ 25, ์ทจ๋ฏธ๋ ์ ํ๋์ง ์์. ๐Name: John, Age: 30 Hobbies: [reading, traveling] "No hobbies selected"๋ก ์ถ๋ ฅ๋ฉ๋๋ค.ํผ ๋ฐ์ดํฐ๋ฅผ DTO๋ก ๊ด๋ฆฌํ๋ฉด ๋ณต์กํจ์ ์ฌ๋ผ์ง๊ณ , ๊น๋ํ๊ฒ ๋ฐ์ดํฐ ๊ด๋ฆฌ๊ฐ ๊ฐ๋ฅํด์ง๋ค!
Spring MVC์์ Command Object๋ ํผ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฒด๋ก ๋ฐ๋ ๋งค์ฐ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ ๋๋ค!
public class UserDto {
private String name;
private int age;
private String[] hobbies;
// Getter and Setter methods
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String[] getHobbies() {
return hobbies;
}
public void setHobbies(String[] hobbies) {
this.hobbies = hobbies;
}
@Override
public String toString() {
return "UserDto{" +
"name='" + name + '\'' +
", age=" + age +
", hobbies=" + Arrays.toString(hobbies) +
'}';
}
}
@Controller
public class UserController {
@PostMapping("/submitForm")
public String submitForm(UserDto userDto, Model model) {
// DTO ๊ฐ์ฒด๋ก ๋ฐ์ ๋ฐ์ดํฐ ์ถ๋ ฅ
System.out.println(userDto);
// ๋ชจ๋ธ์ DTO ๊ฐ์ฒด๋ฅผ ์ถ๊ฐํ์ฌ ๋ทฐ๋ก ์ ๋ฌ
model.addAttribute("user", userDto);
return "formResult"; // ๊ฒฐ๊ณผ ํ์ด์ง๋ก ์ด๋
}
}
UserDto ํด๋์ค: ์ด ํด๋์ค๋ ์ด๋ฆ(name), ๋์ด(age), ์ทจ๋ฏธ(hobbies)๋ผ๋ ํ๋๋ฅผ ๊ฐ์ง๊ณ , ํผ์์ ๋์ด์จ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํฉ๋๋ค. ๊ฐ ํ๋์๋ getter์ setter ๋ฉ์๋๊ฐ ์์ด ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ฒ ์ฃผ๊ณ ๋ฐ์ ์ ์์ต๋๋ค. submitForm ๋ฉ์๋: ํด๋ผ์ด์ธํธ๊ฐ ํผ์ ์ ์ถํ๋ฉด, UserDto ๊ฐ์ฒด๋ก ํผ ๋ฐ์ดํฐ๋ฅผ ์๋์ผ๋ก ๋งคํํฉ๋๋ค. ์ด ๊ฐ์ฒด๋ฅผ ๋ฐ์ ๋ชจ๋ธ์ ์ถ๊ฐํ์ฌ ๋ทฐ๋ก ์ ๋ฌํ ์ ์์ฃ . ๐<form action="/submitForm" method="post">
์ด๋ฆ: <input type="text" name="name" /><br/>
๋์ด: <input type="number" name="age" /><br/>
์ทจ๋ฏธ:
<input type="checkbox" name="hobbies" value="reading" /> ๋
์
<input type="checkbox" name="hobbies" value="traveling" /> ์ฌํ
<input type="checkbox" name="hobbies" value="sports" /> ์ด๋
<br/>
<input type="submit" value="์ ์ก" />
</form>
UserDto ๊ฐ์ฒด๋ก ์๋ ๋งคํ๋ฉ๋๋ค! submitForm ๋ฉ์๋์์ UserDto ๊ฐ์ฒด๋ฅผ ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๊ณ , ๋ทฐ๋ก ์ ๋ฌํฉ๋๋ค. ํผ์์ ์ ๋ฌ๋ ๋ฐ์ดํฐ๋ฅผ ๋ทฐ์์ ๊ฒฐ๊ณผ๋ก ๋ณด์ฌ์ฃผ์! ๐ก
<h1>ํผ ์ ์ถ ๊ฒฐ๊ณผ</h1>
<p>์ด๋ฆ: ${user.name}</p>
<p>๋์ด: ${user.age}</p>
<p>์ทจ๋ฏธ: ${user.hobbies}</p>
@RequestBody ์์ ํด๋ถ! HTTP ์์ฒญ ๋ฐ์ดํฐ๋ฅผ ์์ ์์ฌ๋ก ๋ค๋ฃจ์! ๐JSON๋ถํฐ XML๊น์ง, ํด๋ผ์ด์ธํธ ์์ฒญ ๋ฐ์ดํฐ ์ฒ๋ฆฌ์ ๋ํ์ @RequestBody!
@RequestBody ์ด๋
ธํ
์ด์
- ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฒด๋ก ๋ณํํ์!@RequestBody๋ HTTP ์์ฒญ์ Body์ ๋ด๊ธด ๋ฐ์ดํฐ๋ฅผ Java ๊ฐ์ฒด๋ก ๋ณํํ๋ ์ญํ ์ ํฉ๋๋ค.HttpMessageConverter๋?Spring MVC๋ HttpMessageConverter๋ผ๋ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํด HTTP ์์ฒญ ๋ฐ ์๋ต ๋ฐ์ดํฐ๋ฅผ ๋ณํํฉ๋๋ค!
application/json์ด๋ฉด JSON ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฒด๋ก ๋ณํํ๊ณ , application/xml์ด๋ฉด XML ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฒด๋ก ๋ณํํด์ค๋๋ค! ๐๊ธฐ๋ณธ์ ์ผ๋ก Jackson ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํด JSON ๋ฐ์ดํฐ๋ฅผ Java ๊ฐ์ฒด๋ก ๋ณํํ๊ณ , ๊ฐ์ฒด๋ฅผ JSON ์๋ต์ผ๋ก ๋ณํํ ๋๋ ์ฌ์ฉํฉ๋๋ค.
์ด ๋ชจ๋ ๊ณผ์ ์ด ์๋์ผ๋ก ์ฒ๋ฆฌ๋๊ธฐ ๋๋ฌธ์ ๋ณต์กํ ์ค์ ์์ด ๋ฐ๋ก ์ฌ์ฉํ ์ ์์ด์! ๐
@RequestBody์ @ResponseBody์ ์กฐํฉ@RestController
public class UserController {
@PostMapping("/user")
public UserDto createUser(@RequestBody UserDto userDto) {
// HTTP ์์ฒญ์ Body ๋ฐ์ดํฐ๋ฅผ UserDto ๊ฐ์ฒด๋ก ๋ณํํ์ฌ ์ฒ๋ฆฌ
System.out.println("Received User: " + userDto);
// ์ฒ๋ฆฌ ํ ์๋ต์ผ๋ก ๋ค์ ๋ฐํ (JSON ํํ)
return userDto;
}
}
@RequestBody: ํด๋ผ์ด์ธํธ๊ฐ POST ์์ฒญ์ผ๋ก ๋ณด๋ธ JSON ๋ฐ์ดํฐ๋ฅผ UserDto ๊ฐ์ฒด๋ก ๋ณํํฉ๋๋ค. @ResponseBody: ์ปจํธ๋กค๋ฌ์์ ๋ฐํํ UserDto ๊ฐ์ฒด๋ ๋ค์ JSON ํ์์ผ๋ก ๋ณํ๋์ด ์๋ต์ผ๋ก ์ ์ก๋ฉ๋๋ค. HttpMessageConverter๊ฐ ์๋ ๋ณํ์ ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์, ๊ฐ๋ฐ์๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ์๋ง ์ง์คํ ์ ์์ฃ ! ๐{
"name": "John",
"age": 30,
"hobbies": ["reading", "sports"]
}
@RequestBody๋ฅผ ํตํด JSON ๋ฐ์ดํฐ๋ฅผ UserDto ๊ฐ์ฒด๋ก ๋ณํํ์ฌ ์ฒ๋ฆฌํฉ๋๋ค. @ResponseBody๋ฅผ ํตํด ๋ค์ JSON ์๋ต์ผ๋ก ์ ์ก๋ฉ๋๋ค!๋ชจ๋ธ๊ณผ ๋ทฐ๋ฅผ ํ ๋ฒ์ ์ฒ๋ฆฌํ ๋, JSON ์๋ต์ ์ ์กํ ๋๊น์ง ๋ค์ํ ๋ฆฌํด ํ์ ์ ํ๋์ ์ดํด๋ณด์!
ModelAndView - ๋ชจ๋ธ๊ณผ ๋ทฐ๋ฅผ ํจ๊ป ๋ฐํํ์!ModelAndView๋ ๋ทฐ ์ ๋ณด์ ๋ฐ์ดํฐ(๋ชจ๋ธ)๋ฅผ ๋์์ ์ค์ ํ ์ ์๋ ๊ฐ๋ ฅํ ๋ฆฌํด ํ์
์
๋๋ค.
๋ฐ์ดํฐ์ ๋ทฐ ์ด๋ฆ์ ํ ๋ฒ์ ์ง์ ํ ์ ์์ด์!
@GetMapping("/greeting")
public ModelAndView greeting() {
ModelAndView mav = new ModelAndView("greetView"); // ๋ทฐ ์ด๋ฆ ์ค์
mav.addObject("message", "Hello, World!"); // ๋ชจ๋ธ์ ๋ฐ์ดํฐ ์ถ๊ฐ
return mav; // ๋ชจ๋ธ๊ณผ ๋ทฐ๋ฅผ ํ ๋ฒ์ ๋ฐํ!
}
Model - ๋ฐ์ดํฐ๋ฅผ ๋ทฐ๋ก ์ ๋ฌํ๊ธฐ!Model์ ๋ทฐ์ ์ ๋ฌํ ๋ฐ์ดํฐ๋ง์ ๋ด๋ ๊ฐ์ฒด์
๋๋ค. ์ฃผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๊ณ , ๋ทฐ ์ด๋ฆ์ String์ผ๋ก ๋ฐ๋ก ๋ฐํํฉ๋๋ค! ๐ฆ
@GetMapping("/welcome")
public String welcome(Model model) {
model.addAttribute("message", "Welcome to Spring MVC");
return "welcomeView"; // ๋ทฐ ์ด๋ฆ์ ๋ฌธ์์ด๋ก ๋ฐํ!
}
Map - Java์ ๋งต ๊ฐ์ฒด๋ก ๋ฐ์ดํฐ ์ ๋ฌ!Model๊ณผ ์ ์ฌํ๊ฒ Map๋ ๋ทฐ์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ ๋ ์ฌ์ฉ๋ฉ๋๋ค. Map ๊ฐ์ฒด์ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๊ณ ๋ทฐ ์ด๋ฆ์ ๋ฐ๋ก ์ค์ ํฉ๋๋ค.
@GetMapping("/info")
public String info(Map<String, Object> map) {
map.put("info", "This is some information.");
return "infoView"; // ๋ทฐ ์ด๋ฆ ๋ฐํ!
}
String - ๋ทฐ ์ด๋ฆ์ ๋ฌธ์์ด๋ก ๋ฐํํ์!๊ฐ์ฅ ๋จ์ํ ๋ฆฌํด ํ์
! String์ผ๋ก ๋ทฐ ์ด๋ฆ์ ๋ฐํํ๊ณ , ๋ฐ์ดํฐ๋ Model ๋๋ Map์ ํตํด ์ ๋ฌํฉ๋๋ค. ๐ฏ
@GetMapping("/home")
public String home(Model model) {
model.addAttribute("greeting", "Hello Home!");
return "homeView"; // ๋ทฐ ์ด๋ฆ์ ๋ฌธ์์ด๋ก ๋ฐํ
}
View - ํน์ ๋ทฐ ๊ฐ์ฒด ์ง์ ๋ฐํ!๋ทฐ ๊ฐ์ฒด๋ฅผ ์ง์ ๋ฐํํ๊ณ ์ถ์ ๋๋ View ํ์
์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ํน์ JSP, Thymeleaf ๋ฑ์ ๋ทฐ๋ฅผ ์ง์ ์ง์ ํ ์ ์์ด์!
@GetMapping("/customView")
public View customView() {
return new InternalResourceView("/WEB-INF/views/custom.jsp"); // JSP ํ์ผ ์ง์ ์ง์ !
}
void - ์ง์ ์๋ต ์ฒ๋ฆฌํ๊ธฐ!void๋ ๋ฉ์๋๊ฐ ์๋ต ์์ฒด๋ฅผ ์ง์ ์ฒ๋ฆฌํ ๋ ์ฌ์ฉ๋ฉ๋๋ค. HttpServletResponse๋ก ์ง์ ๋ฐ์ดํฐ๋ฅผ ์์ฑํ๊ฑฐ๋, ๋ทฐ ์ด๋ฆ์ URL์์ ์๋ ์ถ๋ก ํ ๋ ์ฌ์ฉ๋ฉ๋๋ค.
@GetMapping("/autoView")
public void autoView(HttpServletResponse response) throws IOException {
response.getWriter().write("Direct response content");
}
@ResponseBody - ๊ฐ์ฒด๋ฅผ JSON, XML๋ก ๋ณํ!@ResponseBody๋ฅผ ์ฌ์ฉํ๋ฉด Java ๊ฐ์ฒด๋ฅผ JSON ๋๋ XML๋ก ๋ณํํด ์๋ต์ผ๋ก ์ง์ ๋ณด๋ผ ์ ์์ต๋๋ค. ์ฃผ๋ก REST API์์ ๋ง์ด ์ฌ์ฉ๋๋ฉฐ, Spring์ HttpMessageConverter๊ฐ ์๋์ผ๋ก ๊ฐ์ฒด๋ฅผ ์ง๋ ฌํํด์ค๋๋ค! ๐
@GetMapping("/api/data")
@ResponseBody
public DataDto getData() {
return new DataDto("John", 25); // JSON์ผ๋ก ๋ณํ๋์ด ์๋ต๋จ
}
๋ฉ์ง Velog ํฌ์คํ ์ ์ํ ์๊ทน์ ์ธ ์ ๋ชฉ๊ณผ ์ด๋ชจ์ง๋ก ์ด๋ฒ์๋ Spring MVC์ View ์ฒ๋ฆฌ ๊ณผ์ ์ ๋งค๋ ฅ์ ์ผ๋ก ๊พธ๋ฉฐ๋ณผ๊ฒ! ๐
์ฌ์ฉ์์ ์์ฒญ์ด ๋ทฐ๋ก ๋ณํ๋๋ ์ ์ฒด ๊ณผ์ ์ ๋จ๊ณ๋ณ๋ก ์ดํด๋ณด์!
"home"์ด๋ผ๋ ๋ทฐ ์ด๋ฆ์ ๋ฐํํ๋ฉด, ViewResolver๋ ์ด๋ฅผ home.jsp ๊ฐ์ ์ค์ ํ์ผ ๊ฒฝ๋ก๋ก ๋งคํํฉ๋๋ค. ๐๏ธ๋ทฐ ์ด๋ฆ์ prefix์ suffix๋ฅผ ๊ฒฐํฉํด JSP ํ์ผ์ ์ฐพ์๋ด๋ ๋๋ํ ๋ฐฉ๋ฒ!
InternalResourceViewResolver๋ Spring MVC์์ ์ฃผ๋ก ์ฌ์ฉ๋๋ ๋ทฐ ๋ฆฌ์กธ๋ฒ๋ก, ๋
ผ๋ฆฌ์ ์ธ ๋ทฐ ์ด๋ฆ์ ์ค์ ํ์ผ ๊ฒฝ๋ก๋ก ๋ณํํ๋ ์ญํ ์ ํฉ๋๋ค."WEB-INF/views/"์ ๊ฐ์ ๊ฒฝ๋ก์์ ๋ทฐ ํ์ผ์ ์ฐพ๊ฒ ๋ค๋ ์๋ฏธ์ฃ ! .jsp ๊ฐ์ ํ์ผ ํ์ฅ์๋ฅผ ์ค์ ํ์ฌ JSP ํ์ผ์ ์ฌ์ฉํฉ๋๋ค. ๐"board/list" "/WEB-INF/views/" ".jsp" ๊ฒฐ๊ณผ์ ์ผ๋ก /WEB-INF/views/board/list.jsp ๊ฒฝ๋ก์ ์๋ JSP ํ์ผ์ ์ฐพ์์ ๋ทฐ๋ฅผ ๋ ๋๋งํ๊ฒ ๋ฉ๋๋ค! ๐ฏ
InternalResourceViewResolver๋ XML ์ค์ ์์ prefix์ suffix๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ง์ ํ ์ ์์ต๋๋ค:
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
์ด ์ค์ ์ผ๋ก ๋ทฐ ์ด๋ฆ์ด "board/list"์ผ ๋, "/WEB-INF/views/board/list.jsp" ํ์ผ์ ์ฌ์ฉํ๊ฒ ๋ฉ๋๋ค! ๐พ
/list URL๋ก ์์ฒญ์ ๋ณด๋
๋๋ค. list() ๋ฉ์๋๋ก ์ ๋ฌ๋ฉ๋๋ค. "board/list"๋ผ๋ ๋
ผ๋ฆฌ์ ๋ทฐ ์ด๋ฆ์ ๋ฐํํฉ๋๋ค. /WEB-INF/views/board/list.jsp ํ์ผ์ ์ฐพ์ ๋ ๋๋งํฉ๋๋ค! ๐ฏModelAndView ๊ฐ์ฒด์ String ๋ฐํ ๋ฐฉ์์ผ๋ก ๋ทฐ๋ฅผ ์ฝ๊ฒ ์ค์ ํ์!
ModelAndView๋ ๋ทฐ ์ด๋ฆ๊ณผ ๋ชจ๋ธ ๋ฐ์ดํฐ๋ฅผ ํจ๊ป ์ฒ๋ฆฌํ ์ ์๋ ๊ฐ์ฒด๋ก, Spring MVC์์ ๋งค์ฐ ์ ์ฉํ๊ฒ ์ฌ์ฉ๋ฉ๋๋ค.@GetMapping("/example1")
public ModelAndView example1() {
// ๋ทฐ ์ด๋ฆ์ ์์ฑ์์ ์ ๋ฌํ์ฌ ์ง์
ModelAndView mav = new ModelAndView("exampleView");
return mav; // "exampleView"์ธ JSP๊ฐ ๋ ๋๋ง๋จ
}
ModelAndView์ ์์ฑ์๋ฅผ ํตํด ๋ทฐ ์ด๋ฆ์ ๋ช
์์ ์ผ๋ก ์ค์ ํ์ด์. ์ด ์ด๋ฆ์ ๋ฐํ์ผ๋ก JSP ํ์ผ์ ์ฐพ์์ ๋ ๋๋งํฉ๋๋ค! ๐ป@GetMapping("/example2")
public ModelAndView example2() {
ModelAndView mav = new ModelAndView(); // ๋น ๊ฐ์ฒด ์์ฑ
mav.setViewName("exampleView"); // setter๋ก ๋ทฐ ์ด๋ฆ ์ค์
return mav;
}
setViewName() ๋ฉ์๋๋ฅผ ์ฌ์ฉํด ๋ทฐ ์ด๋ฆ์ ์ค์ ํ์ด์. ์์ฑ์ ๋ฐฉ์๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ์ ๊ณตํ์ง๋ง, ๋ ์ ์ฐํ๊ฒ ๋ทฐ ์ด๋ฆ์ ์ง์ ํ ์ ์์ฃ ! ๐ฏString ํ์
์ผ๋ก ๋ทฐ ์ด๋ฆ์ ๋ฐํํ๋ ๋ฐฉ์์ด ์์ต๋๋ค.@GetMapping("/example3")
public String example3() {
return "exampleView"; // String ํ์
์ผ๋ก ๋ทฐ ์ด๋ฆ ๋ฐํ
}
RequestToViewNameTranslator๋ฅผ ์์๋ณด์! ๐๋ทฐ ์ด๋ฆ์ ๋ช ์ํ์ง ์์๋, Spring์ด URL์ ๊ธฐ๋ฐ์ผ๋ก ๋ทฐ๋ฅผ ์๋์ผ๋ก ์ฐพ์์ค๋ค!
RequestToViewNameTranslator๊ฐ ๋ด๋นํ๋ฉฐ, ์์ฒญ ๊ฒฝ๋ก์์ ๋ทฐ ์ด๋ฆ์ ์ถ์ถํ๋ ์ญํ ์ ํ์ฃ ! ๐ฏModel์ด๋ Map ๊ฐ์ฒด๋ง ๋ฐํํ๊ณ ๋ทฐ ์ด๋ฆ์ ์ง์ ํ์ง ์์ ๋ void๋ฅผ ๋ฆฌํดํ์ง๋ง, HttpServletResponse ๊ฐ์ฒด๋ก ์ง์ ์๋ตํ์ง ์์ ๋ ์ด ๊ฒฝ์ฐ, Spring์ ์์ฒญ URL ํจํด์ ๊ธฐ๋ฐ์ผ๋ก ๋ทฐ ์ด๋ฆ์ ์ถ๋ก ํ์ฌ ์๋์ผ๋ก ๊ฒฐ์ ํฉ๋๋ค! ๐
@GetMapping("/example")
public Map<String, Object> example() {
Map<String, Object> model = new HashMap<>();
model.put("message", "Hello, Spring!");
return model; // ๋ทฐ ์ด๋ฆ์ ๋ช
์์ ์ผ๋ก ์ค์ ํ์ง ์์
}
/example์ด๋ฏ๋ก, Spring์ RequestToViewNameTranslator๋ฅผ ํตํด ๋ทฐ ์ด๋ฆ์ example๋ก ์ถ๋ก ํฉ๋๋ค!example.jsp์ ๊ฐ์ ํ์ผ์ ์ฐพ์ ๋ ๋๋งํ๊ฒ ๋ฉ๋๋ค. ๐ผ๏ธ/example ๊ฒฝ๋ก๋ก ์์ฒญ์ ๋ณด๋
๋๋ค. Map ๊ฐ์ฒด๋ง์ ๋ฐํํ๊ณ , ๋ทฐ ์ด๋ฆ์ ๋ช
์์ ์ผ๋ก ์ง์ ํ์ง ์์ต๋๋ค. example์ด๋ผ๋ ๋ทฐ ์ด๋ฆ์ ์๋์ผ๋ก ์ง์ ํฉ๋๋ค. example.jsp์ ๊ฐ์ ํ์ผ์ ์ฐพ์ ๋ ๋๋งํฉ๋๋ค! ๐ปRequestToViewNameTranslator๋ ๋ทฐ ์ด๋ฆ์ ๋ช
์์ ์ผ๋ก ์ง์ ํ์ง ์์์ ๋, ์์ฒญ URL์ ๊ธฐ๋ฐ์ผ๋ก ์๋์ผ๋ก ๋ทฐ ์ด๋ฆ์ ์ถ๋ก ํฉ๋๋ค. /hello4๋ผ๋ฉด, Spring์ hello4๋ผ๋ ์ด๋ฆ์ ๋ทฐ๋ฅผ ์๋์ผ๋ก ๊ฒฐ์ ํ์ฃ ! ๐ก/example๋ก ์์ฒญ์ ๋ณด๋
๋๋ค. Map ๋ฐ์ดํฐ๋ฅผ ๋ฐํํฉ๋๋ค. example.jsp๋ฅผ ๋ ๋๋งํฉ๋๋ค! ๐จredirect:๋ฅผ ํตํด ํด๋ผ์ด์ธํธ๋ฅผ ์ํ๋ ๊ณณ์ผ๋ก ์ด๋์ํค์! ๐๋ฆฌ๋ค์ด๋ ํธ์ ๊ฐ๋
๋ถํฐ RedirectAttributes๋ก ํ๋ผ๋ฏธํฐ๋ฅผ ์ ๋ฌํ๋ ๋ฐฉ๋ฒ๊น์ง, ๋ฆฌ๋ค์ด๋ ํธ์ ๋ชจ๋ ๊ฒ!
redirect: ์ ๋์ด๋ฅผ ๋ถ์ด๋ฉด ๋ฆฌ๋ค์ด๋ ํธ๊ฐ ๋ฐ์ํ๊ณ , ํด๋ผ์ด์ธํธ๋ ํด๋น URL๋ก ๋ค์ ์์ฒญ์ ๋ณด๋ด๊ฒ ๋ฉ๋๋ค! ๐ฏreturn "redirect:/article/list";
/article/list๋ก ์๋์ผ๋ก ๋ฆฌ๋ค์ด๋ ํธ๋ฉ๋๋ค! ๐กRedirectAttributes๋ก ํ๋ผ๋ฏธํฐ ์ ๋ฌํ๊ธฐRedirectAttributes ๊ฐ์ฒด๋ฅผ ์ ๊ณตํ๋ฉฐ, ๋ฆฌ๋ค์ด๋ ํธ๋ ํ์ด์ง์ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ฅผ ์ฝ๊ฒ ์ถ๊ฐํ ์ ์์ฃ ! ๐ ๏ธ@PostMapping("/write")
public String write(BoardDto boardDto, HttpSession session, RedirectAttributes redirectAttributes) {
// ์ธ์
์์ ์ฌ์ฉ์ ์ ๋ณด ๊ฐ์ ธ์ DTO์ ์ค์
MemberDto memberDto = (MemberDto) session.getAttribute("userinfo");
boardDto.setUserId(memberDto.getUserId());
// ๋ฆฌ๋ค์ด๋ ํธ ์ ์ ๋ฌํ ํ๋ผ๋ฏธํฐ ์ค์
redirectAttributes.addAttribute("pgno", "1");
redirectAttributes.addAttribute("key", "");
redirectAttributes.addAttribute("word", "");
// "/article/list"๋ก ๋ฆฌ๋ค์ด๋ ํธ
return "redirect:/article/list";
}
RedirectAttributes๋ฅผ ํตํด ๋ฆฌ๋ค์ด๋ ํธ๋ URL์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ถ๊ฐํ ์ ์์ต๋๋ค!/article/list?pgno=1&key=&word=์ ๊ฐ์ ํํ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค! ๐/write ๊ฒฝ๋ก๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์ถํฉ๋๋ค. RedirectAttributes๋ฅผ ํตํด ์ถ๊ฐ์ ์ธ ํ๋ผ๋ฏธํฐ๋ฅผ ์ค์ ํ๊ณ /article/list๋ก ์ด๋ํฉ๋๋ค. pgno, key, word ํ๋ผ๋ฏธํฐ์ ํจ๊ป ํ์๋ฉ๋๋ค. ๐ฏModel, ModelAndView, @ModelAttribute๋ก ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ฒ ์ ๋ฌํ๋ ๋น๋ฒ ๊ณต๊ฐ!
Map, Model, ModelMap์ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ ์ ๋ฌํ๊ธฐMap, Model, ModelMap์ Spring MVC์์ ๋ทฐ์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ๋ฐฉ๋ฒ์
๋๋ค.Model ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ์ฌ addAttribute() ๋ฉ์๋๋ก ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํฉ๋๋ค. ์ด ๋ฐ์ดํฐ๋ ๋ทฐ์์ ๋ ๋๋ง๋์ด ์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ง์ฃ ! ๐ฏ@GetMapping("/example")
public String example(Model model) {
model.addAttribute("message", "Hello, Spring MVC");
return "exampleView"; // ๋ทฐ ์ด๋ฆ์ ๋ฐํ
}
Model ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํด "message"๋ผ๋ ๋ฐ์ดํฐ๋ฅผ ๋ทฐ๋ก ์ ๋ฌํฉ๋๋ค.exampleView)์์ ์ด message ๊ฐ์ ํ์ฉํด ๋ฐ์ดํฐ๋ฅผ ํ๋ฉด์ ํ์ํ ์ ์์ด์! ๐ฅ๏ธModelAndView๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ์ ๋ทฐ๋ฅผ ํจ๊ป ์ ๋ฌํ๊ธฐModelAndView๋ ๋ฐ์ดํฐ(๋ชจ๋ธ)์ ๋ทฐ ์ด๋ฆ์ ํ ๋ฒ์ ์ค์ ํ ์ ์๋ ๊ฐ์ฒด์
๋๋ค.@GetMapping("/example2")
public ModelAndView example2() {
ModelAndView mav = new ModelAndView("exampleView");
mav.addObject("message", "Hello, ModelAndView");
return mav; // ๋ทฐ์ ๋ฐ์ดํฐ๋ฅผ ํจ๊ป ๋ฐํ
}
ModelAndView ๊ฐ์ฒด๋ก ๋ทฐ ์ด๋ฆ("exampleView")๊ณผ ๋ฐ์ดํฐ("message")๋ฅผ ํจ๊ป ๋ฐํํฉ๋๋ค.@ModelAttribute๋ฅผ ์ฌ์ฉํ์ฌ ์๋์ผ๋ก ๋ฐ์ดํฐ ์ ๋ฌํ๊ธฐ@ModelAttribute๋ ์ปจํธ๋กค๋ฌ ๋ฉ์๋๊ฐ ์๋์ผ๋ก ๋ชจ๋ธ์ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๋๋ก ๋์์ค๋๋ค.@ModelAttribute("user")
public User addUser() {
return new User("John", 30);
}
User ๊ฐ์ฒด๋ฅผ ๋ฐํํ๊ณ , Spring์ ์๋์ผ๋ก "user"๋ผ๋ ์ด๋ฆ์ผ๋ก ๋ชจ๋ธ์ ์ถ๊ฐํฉ๋๋ค."user" ๋ฐ์ดํฐ๋ฅผ ํ์ฉํ ์ ์๊ฒ ๋ฉ๋๋ค! ๐ค์ธ ๊ฐ์ง ๋ฐฉ๋ฒ์ผ๋ก ๋ทฐ(View)์ ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๋ ๋น๋ฒ ๊ณต๊ฐ!
Map<String, Object>๋ก ๋ทฐ์ ๋ฐ์ดํฐ ์ ๋ฌํ๊ธฐMap์ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๋ทฐ๋ก ์ ๋ฌํ๋ ๋ฐฉ์์ ํค-๊ฐ ์์ ์ด์ฉํด ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๊ณ ์ ๋ฌํ๋ ๋ฐฉ๋ฒ์
๋๋ค.Map ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํด ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ ์ ์์ด์! ๐ ๏ธ@GetMapping("/example1")
public String example1(Map<String, Object> model) {
model.put("message", "Hello from Map!");
return "home"; // ๋ทฐ ์ด๋ฆ ๋ฐํ
}
Map ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํด "message"๋ผ๋ ํค์ "Hello from Map!" ๊ฐ์ ์ถ๊ฐํฉ๋๋ค. ๋ทฐ์์ "message"๋ผ๋ ์ด๋ฆ์ผ๋ก ์ด ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ ์ ์์ด์! ๐ฆModel๋ก ๋ทฐ์ ๋ฐ์ดํฐ ์ ๋ฌํ๊ธฐModel์ Spring MVC์์ ์ ๊ณตํ๋ ์ธํฐํ์ด์ค๋ก, ๋ทฐ์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ ๋ ๋ ์ง๊ด์ ์ธ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค.addAttribute() ๋ฉ์๋๋ฅผ ์ฌ์ฉํด ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๋ฉด, ๋ทฐ์์ ์ฝ๊ฒ ์ ๊ทผํ ์ ์์ฃ ! ๐ฏ@GetMapping("/example2")
public String example2(Model model) {
model.addAttribute("message", "Hello from Model!");
return "home"; // ๋ทฐ ์ด๋ฆ ๋ฐํ
}
Model ๊ฐ์ฒด๋ฅผ ํตํด "message"๋ผ๋ ์ด๋ฆ์ผ๋ก "Hello from Model!" ๊ฐ์ ๋ทฐ์ ์ ๋ฌํฉ๋๋ค. ๋ทฐ๋ ์ด ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค! ๐จModelMap์ผ๋ก ๋ทฐ์ ๋ฐ์ดํฐ ์ ๋ฌํ๊ธฐModelMap์ Model๊ณผ ๋งค์ฐ ์ ์ฌํ์ง๋ง, Map์ฒ๋ผ ์๋ํ๋ ํด๋์ค์
๋๋ค.addAttribute() ๋ฉ์๋๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ ์ ์๊ณ , Map๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค! ๐ ๏ธ@GetMapping("/example3")
public String example3(ModelMap model) {
model.addAttribute("message", "Hello from ModelMap!");
return "home"; // ๋ทฐ ์ด๋ฆ ๋ฐํ
}
ModelMap ๊ฐ์ฒด๋ก "message"์ "Hello from ModelMap!" ๊ฐ์ ์ถ๊ฐํฉ๋๋ค. ์ด ๋ฐ์ดํฐ๋ ๋ทฐ์์ ๋ฐ๋ก ์ฌ์ฉํ ์ ์์ฃ ! ๐๏ธaddAttribute๋ถํฐ mergeAttributes๊น์ง, Model ๊ฐ์ฒด์ ํ์ ๋ฉ์๋ ์๋ฒฝ ํด๋ถ!
addAttribute(String name, Object value) - ์ด๋ฆ๊ณผ ๊ฐ์ ํจ๊ป ์ถ๊ฐํ๊ธฐ!model.addAttribute("message", "Hello, Spring!");
"message"๋ผ๋ ์ด๋ฆ์ผ๋ก "Hello, Spring!" ๊ฐ์ ๋ทฐ๋ก ์ ๋ฌํฉ๋๋ค. ๋ทฐ์์๋ message๋ผ๋ ์ด๋ฆ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ ์ ์์ด์! ๐ฌaddAttribute(Object value) - ์ด๋ฆ ์์ด ๊ฐ์ ์ถ๊ฐํ๊ณ ์๋์ผ๋ก ์ด๋ฆ ์ค์ ํ๊ธฐ!model.addAttribute(new User("John", 25));
User ๊ฐ์ฒด๋ฅผ Model์ ์ถ๊ฐํ์ผ๋ฉฐ, Spring์ด ์๋์ผ๋ก user๋ผ๋ ์ด๋ฆ์ ์ค์ ํฉ๋๋ค.user ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ ์ ์์ฃ ! ๐คaddAllAttributes(Collection<?> values) - Collection ๋ฐ์ดํฐ๋ฅผ ํ ๋ฒ์ ์ถ๊ฐํ๊ธฐ!Collection ํ์
์ ์ฌ๋ฌ ๋ฐ์ดํฐ๋ฅผ ํ ๋ฒ์ Model์ ์ถ๊ฐํ ์ ์์ต๋๋ค!List<String> messages = Arrays.asList("Message1", "Message2", "Message3");
model.addAllAttributes(messages);
addAllAttributes(Map<String, ?> attributes) - Map ๋ฐ์ดํฐ๋ฅผ ํ ๋ฒ์ ์ถ๊ฐํ๊ธฐ!Map ๊ฐ์ฒด๋ก ์ฌ๋ฌ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ํ ๋ฒ์ Model์ ์ถ๊ฐํ ์ ์์ต๋๋ค.Map<String, Object> data = new HashMap<>();
data.put("message", "Hello, Spring!");
data.put("user", new User("John", 25));
model.addAllAttributes(data);
message์ user ๋ฐ์ดํฐ๋ฅผ Map์ผ๋ก ํ ๋ฒ์ Model์ ์ถ๊ฐํ์ฌ ๋ทฐ์์ ์ฌ์ฉํ ์ ์๋๋ก ์ค์ ํฉ๋๋ค. ๐mergeAttributes(Map<String, ?> attributes) - ๋ฐ์ดํฐ ๋ณํฉํ๊ธฐ!mergeAttributes()๋ ๊ธฐ์กด Model ๋ฐ์ดํฐ์ ์๋ก์ด ๋ฐ์ดํฐ๋ฅผ ๋ณํฉํ ๋ ์ฌ์ฉ๋ฉ๋๋ค.Map<String, Object> additionalData = new HashMap<>();
additionalData.put("status", "active");
model.mergeAttributes(additionalData);
status ๋ฐ์ดํฐ๊ฐ ์๋ค๋ฉด ๋ฎ์ด์ฐ์ง ์๊ณ , ์๋ก์ด ๋ฐ์ดํฐ๋ง ๋ณํฉํฉ๋๋ค.containsAttribute(String name) - ํน์ ์์ฑ์ด ์๋์ง ํ์ธํ๊ธฐ!containsAttribute()๋ Model์ ํน์ ์์ฑ์ด ์กด์ฌํ๋์ง ํ์ธํ๋ ๋ฉ์๋์
๋๋ค.true, ์์ผ๋ฉด false๋ฅผ ๋ฐํํด์! ๐if (model.containsAttribute("message")) {
// "message" ์์ฑ์ด ์กด์ฌํ๋ ๊ฒฝ์ฐ์๋ง ์ฒ๋ฆฌ
}
message ์์ฑ์ด Model์ ์๋์ง ํ์ธํ๊ณ , ์์ผ๋ฉด ๊ทธ์ ๋ง๋ ์ฒ๋ฆฌ๋ฅผ ํฉ๋๋ค.addAttribute๋ถํฐ mergeAttributes๊น์ง, Model ๊ฐ์ฒด์ ํ์ ๋ฉ์๋ ์๋ฒฝ ํด๋ถ!
addAttribute(String name, Object value) - ์ด๋ฆ๊ณผ ๊ฐ์ ํจ๊ป ์ถ๊ฐํ๊ธฐ!model.addAttribute("message", "Hello, Spring!");
"message"๋ผ๋ ์ด๋ฆ์ผ๋ก "Hello, Spring!" ๊ฐ์ ๋ทฐ๋ก ์ ๋ฌํฉ๋๋ค. ๋ทฐ์์๋ message๋ผ๋ ์ด๋ฆ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ ์ ์์ด์! ๐ฌaddAttribute(Object value) - ์ด๋ฆ ์์ด ๊ฐ์ ์ถ๊ฐํ๊ณ ์๋์ผ๋ก ์ด๋ฆ ์ค์ ํ๊ธฐ!model.addAttribute(new User("John", 25));
User ๊ฐ์ฒด๋ฅผ Model์ ์ถ๊ฐํ์ผ๋ฉฐ, Spring์ด ์๋์ผ๋ก user๋ผ๋ ์ด๋ฆ์ ์ค์ ํฉ๋๋ค.user ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ ์ ์์ฃ ! ๐คaddAllAttributes(Collection<?> values) - Collection ๋ฐ์ดํฐ๋ฅผ ํ ๋ฒ์ ์ถ๊ฐํ๊ธฐ!Collection ํ์
์ ์ฌ๋ฌ ๋ฐ์ดํฐ๋ฅผ ํ ๋ฒ์ Model์ ์ถ๊ฐํ ์ ์์ต๋๋ค!List<String> messages = Arrays.asList("Message1", "Message2", "Message3");
model.addAllAttributes(messages);
addAllAttributes(Map<String, ?> attributes) - Map ๋ฐ์ดํฐ๋ฅผ ํ ๋ฒ์ ์ถ๊ฐํ๊ธฐ!Map ๊ฐ์ฒด๋ก ์ฌ๋ฌ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ํ ๋ฒ์ Model์ ์ถ๊ฐํ ์ ์์ต๋๋ค.Map<String, Object> data = new HashMap<>();
data.put("message", "Hello, Spring!");
data.put("user", new User("John", 25));
model.addAllAttributes(data);
message์ user ๋ฐ์ดํฐ๋ฅผ Map์ผ๋ก ํ ๋ฒ์ Model์ ์ถ๊ฐํ์ฌ ๋ทฐ์์ ์ฌ์ฉํ ์ ์๋๋ก ์ค์ ํฉ๋๋ค. ๐mergeAttributes(Map<String, ?> attributes) - ๋ฐ์ดํฐ ๋ณํฉํ๊ธฐ!mergeAttributes()๋ ๊ธฐ์กด Model ๋ฐ์ดํฐ์ ์๋ก์ด ๋ฐ์ดํฐ๋ฅผ ๋ณํฉํ ๋ ์ฌ์ฉ๋ฉ๋๋ค.Map<String, Object> additionalData = new HashMap<>();
additionalData.put("status", "active");
model.mergeAttributes(additionalData);
status ๋ฐ์ดํฐ๊ฐ ์๋ค๋ฉด ๋ฎ์ด์ฐ์ง ์๊ณ , ์๋ก์ด ๋ฐ์ดํฐ๋ง ๋ณํฉํฉ๋๋ค.containsAttribute(String name) - ํน์ ์์ฑ์ด ์๋์ง ํ์ธํ๊ธฐ!containsAttribute()๋ Model์ ํน์ ์์ฑ์ด ์กด์ฌํ๋์ง ํ์ธํ๋ ๋ฉ์๋์
๋๋ค.true, ์์ผ๋ฉด false๋ฅผ ๋ฐํํด์! ๐if (model.containsAttribute("message")) {
// "message" ์์ฑ์ด ์กด์ฌํ๋ ๊ฒฝ์ฐ์๋ง ์ฒ๋ฆฌ
}
message ์์ฑ์ด Model์ ์๋์ง ํ์ธํ๊ณ , ์์ผ๋ฉด ๊ทธ์ ๋ง๋ ์ฒ๋ฆฌ๋ฅผ ํฉ๋๋ค.ModelAndView๋ก ๋ทฐ์ ๋ฐ์ดํฐ๋ฅผ ํ ๋ฒ์ ์ค์ ํ์! ๐๋ทฐ ์ด๋ฆ๊ณผ ๋ชจ๋ธ ๋ฐ์ดํฐ๋ฅผ ๋์ ์ฒ๋ฆฌํ๋ ModelAndView์ ํต์ฌ ํ์ฉ๋ฒ!
setViewName(String viewName) - ๋ทฐ ์ด๋ฆ ์ค์ ํ๊ธฐsetViewName() ๋ฉ์๋๋ ๋ ๋๋งํ ๋ทฐ ์ด๋ฆ์ ์ง์ ํ๋ ๋ฉ์๋์
๋๋ค. ์ด ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด ์ปจํธ๋กค๋ฌ์์ ์ด๋ค ๋ทฐ๋ฅผ ๋ฐํํ ์ง ๋ช
ํํ๊ฒ ์ค์ ํ ์ ์์ด์! mav.setViewName("home");
"home"์ผ๋ก ์ค์ ํฉ๋๋ค. Spring MVC๋ ์ด ์ด๋ฆ์ ์ฌ์ฉํด home.jsp๋ home.html ๋ฑ์ ์ค์ ๋ทฐ ํ์ผ์ ์ฐพ์์ ๋ ๋๋งํฉ๋๋ค! ๐ addObject(String name, Object value) - ๋ทฐ์ ์ ๋ฌํ ๋ฐ์ดํฐ ์ถ๊ฐํ๊ธฐaddObject() ๋ฉ์๋๋ ๋ชจ๋ธ ๋ฐ์ดํฐ๋ฅผ ๋ทฐ์ ์ถ๊ฐํ ๋ ์ฌ์ฉ๋ฉ๋๋ค.mav.addObject("message", "Welcome to Spring MVC!");
"message"๋ผ๋ ์ด๋ฆ์ผ๋ก "Welcome to Spring MVC!" ๊ฐ์ ๋ชจ๋ธ์ ์ถ๊ฐํฉ๋๋ค.message๋ผ๋ ์ด๋ฆ์ผ๋ก ์ด ๋ฐ์ดํฐ๋ฅผ ํ์ฉํ ์ ์์ต๋๋ค! ๐ฌModelAndView ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ์์ ์ฝ๋@GetMapping("/example")
public ModelAndView example() {
// ModelAndView ๊ฐ์ฒด ์์ฑ
ModelAndView mav = new ModelAndView();
// ๋ฐ์ดํฐ ์ถ๊ฐ
mav.addObject("message", "Welcome to Spring MVC!");
// ๋ทฐ ์ด๋ฆ ์ค์
mav.setViewName("home");
// ModelAndView ๊ฐ์ฒด ๋ฐํ
return mav;
}
ModelAndView ๊ฐ์ฒด ์์ฑ: ๋น ModelAndView ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค. "message"๋ผ๋ ์ด๋ฆ์ผ๋ก "Welcome to Spring MVC!" ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํฉ๋๋ค. "home"์ผ๋ก ์ค์ ํฉ๋๋ค. ModelAndView ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ฉด Spring MVC๊ฐ ๋ทฐ์ ๋ชจ๋ธ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํด ๋ทฐ๋ฅผ ๋ ๋๋งํฉ๋๋ค! ๐ฅ๏ธModelAndView๋ ๋์ ์ธ ๋ฐ์ดํฐ์ ์ง์ ๋ ๋ทฐ๋ฅผ ํจ๊ป ์ฒ๋ฆฌํด์ผ ํ ๋ ์ ์ฉํฉ๋๋ค! @PathVariable๋ก URI ๊ฒฝ๋ก์์ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ์! ๐URL์์ ๋์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ RESTful ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ํต์ฌ!
@PathVariable์ด๋?@PathVariable์ URI ๊ฒฝ๋ก์ ์ผ๋ถ๋ฅผ ๋ณ์๋ก ์ถ์ถํ์ฌ ์ปจํธ๋กค๋ฌ ๋ฉ์๋๋ก ์ ๋ฌํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค./users/{username} ๊ฒฝ๋ก์์ {username}์ ํ
ํ๋ฆฟ ๋ณ์๋ก ๋์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋ ๋ถ๋ถ์
๋๋ค! http://localhost/blog/123/45
์ URL์์ 123์ userId, 45๋ articleNo๋ก ๋ฉ์๋์ ์ ๋ฌ๋ฉ๋๋ค! ๐ฆ
@PathVariable์ ์ฌ์ฉํ ์ปจํธ๋กค๋ฌ ๋ฉ์๋@PathVariable์ ์ฌ์ฉํด URL ๊ฒฝ๋ก์์ ๋์ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ๊ณ , ์ด๋ฅผ ๋ฉ์๋ ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌํ๋ ์์๋ฅผ ์ดํด๋ณด์! ๐
@GetMapping("/blog/{userId}/{articleNo}")
public String viewArticle(@PathVariable("userId") String userId,
@PathVariable("articleNo") int articleNo,
Model model) {
// ์ฒ๋ฆฌ ๋ก์ง (์: ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ํด๋น article ์ ๋ณด ์กฐํ)
model.addAttribute("userId", userId);
model.addAttribute("articleNo", articleNo);
return "blog/view";
}
/blog/{userId}/{articleNo} ๊ฒฝ๋ก์์ {userId}์ {articleNo}๋ฅผ ์ฌ์ฉํด ๋์ ๋ณ์๋ฅผ ์ค์ ํ์ต๋๋ค.@PathVariable๋ก ๋ฐ์ดํฐ ์ถ์ถ: ํด๋ผ์ด์ธํธ๊ฐ /blog/123/45๋ก ์์ฒญ์ ๋ณด๋ด๋ฉด, 123์ userId, 45๋ articleNo๋ก ๊ฐ๊ฐ ๋ฉ์๋ ํ๋ผ๋ฏธํฐ์ ์ ๋ฌ๋ฉ๋๋ค.userId์ articleNo๋ฅผ Model ๊ฐ์ฒด์ ์ถ๊ฐํ์ฌ ๋ทฐ์์ ์ฌ์ฉํ ์ ์๋๋ก ์ค๋นํฉ๋๋ค!"blog/view"๋ ๋ทฐ ์ด๋ฆ์ ๋ฐํํ๋ฉฐ, blog/view.jsp์ ๊ฐ์ ๋ทฐ ํ์ผ์ด ๋ ๋๋ง๋ฉ๋๋ค! ๐ฅ๏ธ/users/{username} ๊ฒฝ๋ก๋ฅผ ์ฌ์ฉํด ๊ฐ ์ฌ์ฉ์์ ํ๋กํ ์ ๋ณด๋ฅผ ์กฐํํ ์ ์์ด์! ๐ค /blog/{userId}/{articleNo} ๊ฒฝ๋ก๋ฅผ ํตํด ํน์ ์ฌ์ฉ์์ ๊ฒ์๊ธ ์ ๋ณด๋ฅผ ์กฐํํ ์ ์์ต๋๋ค! ๐ /products/{productId} ๊ฒฝ๋ก๋ก ํน์ ์ ํ์ ์์ธ ์ ๋ณด๋ฅผ ํ์ธํ ์ ์์ด์! ๐Spring ์ ํ๋ฆฌ์ผ์ด์ ์ด ์์๋๊ณ , ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ์ฒ๋ฆฌํ๋ ๋ชจ๋ ๋จ๊ณ!
web.xml ํ์ผ์ด ๋ก๋๋๋ฉฐ, Spring MVC์ ํต์ฌ ๊ตฌ์ฑ ์์๋ค์ ์ค์ ํ๋๋ฐ ์ค์ํ ์ญํ ์ ํฉ๋๋ค! ๐ ๏ธContextLoaderListener ์์ฑ - ๋ฃจํธ ์ ํ๋ฆฌ์ผ์ด์
์ปจํ
์คํธ ๋ก๋ฉContextLoaderListener๊ฐ ์์ฑ๋์ด ๋ฃจํธ ์ ํ๋ฆฌ์ผ์ด์
์ปจํ
์คํธ๋ฅผ ๋ก๋ฉํฉ๋๋ค. root-context.xml ๋ก๋ฉ - ๋น์ฆ๋์ค ๋ก์ง ์ด๊ธฐํroot-context.xml ํ์ผ์ ํตํด ์๋น์ค ํด๋์ค, DAO ๊ฐ์ฒด, ์ํฐํฐ๋ค์ด ์ด๊ธฐํ๋ฉ๋๋ค.DispatcherServlet ์์ฑ - ๋ชจ๋ ์์ฒญ์ ์ค์ ๊ด์ ํDispatcherServlet์ ๋ชจ๋ ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ์ฒ๋ฆฌํ๋ ํ๋ก ํธ ์ปจํธ๋กค๋ฌ๋ก, Spring MVC์ ํต์ฌ ๊ตฌ์ฑ ์์์
๋๋ค.DispatcherServlet ์ค์ - servlet-context.xml ๋ก๋ฉservlet-context.xml ํ์ผ์ ๋ก๋ฉํ์ฌ ์ปจํธ๋กค๋ฌ, ๋ทฐ ๋ฆฌ์กธ๋ฒ, ๋ฉ์์ง ๋ณํ๊ธฐ ๋ฑ์ ์ค์ ํฉ๋๋ค.