CHAP.08 MVC ํŒจํ„ด์˜ ์ดํ•ด

1. MVC ํŒจํ„ด

๋””์ž์ธ ํŒจํ„ด

  • ๋””์ž์ธ ํŒจํ„ด(Design Pattern)
    • ๊ฑด์ถ•ํ•™์  ๊ด€์ ์—์„œ ์ถœ๋ฐœํ•œ ๊ฐœ๋…
    • 1994๋…„ Gof์˜ <<Design Patterns: Elements of Reusable Object-Oriented Software>>๋ฅผ ํ†ตํ•ด ์†Œํ”„ํŠธ์›จ์–ด ์„ค๊ณ„์—์„œ ๊ณตํ†ต์ ์œผ๋กœ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์— ๋Œ€ํ•œ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์†”๋ฃจ์…˜์œผ๋กœ ์ œ์‹œ
    • Gof์˜ ๋””์ž์ธ ํŒจํ„ด์€ ์ƒ์„ฑ, ๊ตฌ์กฐ, ํ–‰๋™, ๋™์‹œ ์‹คํ–‰ ๋“ฑ์˜ ๋ฌธ์ œ์˜ ๋Œ€ํ•ด ์—ฌ๋Ÿฌ ํŒจํ„ด์„ ์ œ์‹œํ•˜๊ณ  ์žˆ์œผ๋ฉฐ UML ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ์„ ์ด์šฉํ•ด ๊ตฌ์กฐ ํ‘œํ˜„
  • UML(Unified Modeling Language)
    • ๊ฐ์ฒด์ง€ํ–ฅ ์„ค๊ณ„์™€ ๊ตฌํ˜„์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์ง„ ์ผ์ข…์˜ ๋ชจ๋ธ๋ง ์–ธ์–ด
    • ์‹œ์Šคํ…œ ๋ถ„์„, ์„ค๊ณ„์— ํ•„์š”ํ•œ ๋‚ด์šฉ์„ ์—ฌ๋Ÿฌ ๋‹ค์ด์–ด๊ทธ๋žจ ํ˜•ํƒœ๋กœ ์ •์˜ํ•œ ๊ทœ๊ฒฉ

์ถ”์ƒ ํŒฉํ† ๋ฆฌ ํŒจํ„ด

  • ์ถ”์ƒ(Abstract): ์ž๋ฐ”์˜ ์ถ”์ƒ ํด๋ž˜์Šค Abstract Class์—๋„ ์‚ฌ์šฉ๋˜๋Š” ํ‘œํ˜„์œผ๋กœ ๊ตฌ์ฒด์ ์ธ ๋‚ด์šฉ์˜ ๊ตฌํ˜„์„ ํ•˜์œ„ ๊ฐ์ฒด์— ์œ„์ž„ํ•˜๋Š” ๋ชจ๋ธ
  • ํŒฉํ† ๋ฆฌ(Factory): ๋””์ž์ธ ํŒจํ„ด์—์„œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์—ญํ• 
  • ์ถ”์ƒํŒฉํ† ๋ฆฌ๋Š” ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์„ ๋ณ„๋„๋กœ ๊ตฌํ˜„ํ•˜๋˜ ๊ด€๋ จ๋œ ๊ตฌ์ฒด์ ์ธ ๊ตฌํ˜„์„ ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ๋‹ด๋‹นํ•˜๊ฒŒ ํ•˜๋Š” ์„ค๊ณ„ ๋ชจ๋ธ
  • ์ถ”์ƒ ํŒฉํ† ๋ฆฌ ํŒจํ„ด UML ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ[๋ณ„๋„ ์ด๋ฏธ์ง€ ์ถ”๊ฐ€]

MVC ํŒจํ„ด

  • Model-View-Controller์˜ ์•ฝ์–ด
  • GUI ๊ธฐ๋ฐ˜์˜ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์— ์‚ฌ์šฉ๋˜๋Š” ๋””์ž์ธ ํŒจํ„ด
  • ๋ฐฑ ์—”๋“œ ๊ธฐ๋ฐ˜์˜ ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์˜ ๊ธฐ๋ณธ๋ชจ๋ธ
    • ๋ชจ๋ฐ”์ผ ์•ฑ ๋ฐ FE ๊ธฐ๋ฐ˜ ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์ด ๋Š˜์–ด๋‚˜๋ฉด์„œ MVP(Model-View-Presenter), MVVM(Model-View-ViewModel)๊ณผ ๊ฐ™์€ ํŒจํ„ด๋„ ๋„๋ฆฌ ์‚ฌ์šฉ๋จ
  • MVC ํŒจํ„ด์˜ ๋ชฉ์ ์€ ํ™”๋ฉด๊ณผ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ ์ฝ”๋“œ๊ฐ„ ์ข…์†์„ฑ์„ ์ค„์ด๋Š” ๊ฒƒ
    • ๊ตฌ์„ฑ์š”์†Œ๊ฐ„ ์—ญํ• ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ์‰ฝ๊ฒŒ ๋ถ„๋ฆฌํ•˜๊ณ  ํ˜‘์—…์— ์šฉ์ด
  • MVCํŒจํ„ด ๊ตฌ์กฐ[๋ณ„๋„ ์ด๋ฏธ์ง€ ์ถ”๊ฐ€]

  • ๋ชจ๋ธ(Model)
    • ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์˜์—ญ
    • ์ผ๋ฐ˜์ ์œผ๋กœ DB์™€ ์—ฐ๋™์„ ์œ„ํ•œ DAO(Data Access Object) ํด๋ž˜์Šค์™€ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ํ‘œํ˜„ํ•˜๋Š” DO(Data Object, ์—”ํ‹ฐํ‹ฐ ํด๋ž˜์Šค) ๋“ฑ์œผ๋กœ ๊ตฌ์„ฑ
    • ๋ชจ๋ธ์€ ๋ทฐ๋‚˜ ์ปจํŠธ๋กค๋Ÿฌ์— ๋…๋ฆฝ์ ์ธ ๊ตฌ์กฐ๋กœ DB์ฒ˜๋ฆฌ๋ฅผ ํ•„์š”๋กœ ํ•˜๋Š” ์—ฌ๋Ÿฌ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๊ณต์œ  ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์•„๋‹Œ ๊ฒฝ์šฐ์—๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  • ๋ทฐ(View)
    • ํ™”๋ฉด์˜ ๊ตฌ์„ฑ์„ ๋‹ด๋‹นํ•˜๋Š” ์˜์—ญ
    • ์ฃผ์–ด์ง„ ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ์šฉ๋„๋กœ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋žŒ์ง
    • ๋ทฐ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ์‹์€ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Œ
    • ๋ทฐ ์˜์—ญ์˜ ๊ตฌํ˜„์„ ์œ„ํ•ด ๋ทฐ ํ…œํ”Œ๋ฆฟ ์—”์ง„์ด ์‚ฌ์šฉ๋˜๋ฉฐ, JSP ์—ญ์‹œ ์ด๋Ÿฌํ•œ ๋ทฐ ํ…œํ”Œ๋ฆฟ ์—”์ง„ ์ค‘ ํ•˜๋‚˜
    • HTML ์ด์™ธ์— EL, JSTL๋“ฑ์„ ์‚ฌ์šฉํ•ด ์ปจํŠธ๋กค๋Ÿฌ๋กœ๋ถ€ํ„ฐ ์ „๋‹ฌ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ถœ๋ ฅํ•˜๊ณ  HTML, CSS ๋“ฑ์„ ํ†ตํ•ด ํ™”๋ฉด ๋””์ž์ธ
    • ๋ทฐ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋ธ, ์ปจํŠธ๋กค๋Ÿฌ์™€์˜ ์ข…์†Œ์„ฑ์ด ์—†๋„๋ก ๊ตฌํ˜„
  • ์ปจํŠธ๋กค๋Ÿฌ(Controller)
    • MVCํŒจํ„ด์˜ ํ•ต์‹ฌ์œผ๋กœ ๋ชจ๋“  ์‚ฌ์šฉ์ž ์š”์ฒญ์˜ ์ค‘์‹ฌ
    • ์‚ฌ์šฉ์ž ์š”์ฒญ์€ ํŠน์ • ๋ทฐ์— ๋ฐ”๋กœ ์ „๋‹ฌ๋˜์ง€ ์•Š๊ณ  ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ
    • ์ปจํŠธ๋กค๋Ÿฌ๋Š” ์‚ฌ์šฉ์ž ์š”์ฒญ์— ๋”ฐ๋ผ ๋ชจ๋ธ์„ ํ†ตํ•ด DB์™€ ์—ฐ๋™ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋ทฐ์— ์ „๋‹ฌ
    • ๋ทฐ๋กœ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด์žˆ๋Š” DO ํ˜น์€ List<DO> ํ˜•ํƒœ์˜ ๊ฐ์ฒด๋ฅผ request์— ์ €์žฅํ•œ ํ›„ ํฌ์›Œ๋”ฉ
    • ์ปจํŠธ๋กค๋Ÿฌ๋Š” ํŠน์ • ๋ทฐ๋ฅผ ์ง€์ •ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ทฐ์™€ ์ข…์†๊ด€๊ณ„๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ๋ฐ–์— ์—†์Œ
      • ํ”„๋กœ์ ํŠธ์˜ ๊ทœ๋ชจ๊ฐ€ ํด์ˆ˜๋ก ์ปจํŠธ๋กค๋Ÿฌ๋Š” ๋ณต์žกํ•ด์ง€๊ณ  ๊ด€๋ฆฌ๊ฐ€ ์–ด๋ ค์›Œ์ง€๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์Œ
  • ์ปจํŠธ๋กค๋Ÿฌ์˜ ๊ตฌํ˜„
    • JSP, ์„œ๋ธ”๋ฆฟ ๋ชจ๋‘ ๊ฐ€๋Šฅ
    • JSP: ๊ฐ„๋‹จํ•œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ๋•Œ ์œ ๋ฆฌ
    • ์„œ๋ธ”๋ฆฟ: ๊ทœ๋ชจ ํ™•์žฅ๊ณผ ํ–ฅํ›„ ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ๋กœ์˜ ํ™•์žฅ ๋“ฑ์— ์œ ๋ฆฌ
    • ์ปจํŠธ๋กค๋Ÿฌ ํ˜ธ์ถœ
  • ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ์„ธ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•
    • ์‚ฌ์šฉ์ž ์š”์ฒญ๋งˆ๋‹ค ์ปจํŠธ๋กค๋Ÿฌ ๋งŒ๋“ค๊ธฐ
    • ํŠน์ • ๋ชจ๋“ˆ ๋‹จ์œ„๋กœ ํ•˜๋‚˜์˜ ์ปจํŠธ๋กค๋Ÿฌ ์•ˆ์—์„œ ์—ฌ๋Ÿฌ ์š”์ฒญ ๋‹จ์œ„๋ฅผ ๊ตฌ๋ถ„ํ•˜์—ฌ ์ฒ˜๋ฆฌ
    • Front ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๋”ฐ๋กœ ๋‘์–ด ๋ชจ๋“  ์š”์ฒญ์„ ํ•˜๋‚˜์˜ ์ปจํŠธ๋กค๋Ÿฌ๋กœ ๋ชจ์€ ๋‹ค์Œ ์š”์ฒญ์— ๋”ฐ๋ผ ๊ตฌํ˜„ ์ปจํŠธ๋กค๋Ÿฌ ํ˜ธ์ถœ

2. ์„œ๋ธ”๋ฆฟ ์ปจํŠธ๋กค๋Ÿฌ ์„ค๊ณ„

ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ ์ฒ˜๋ฆฌ

  • ์ปจํŠธ๋กค๋Ÿฌ์˜ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๊ธฐ๋Šฅ ์„ธ๊ฐ€์ง€
    • ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ ์ฒ˜๋ฆฌ
      • ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์„ ๋‹จ์ผ ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์ฒ˜๋ฆฌํ•  ๊ฒƒ์ธ์ง€ ๊ฐœ๋ณ„ ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์ฒ˜๋ฆฌํ•  ๊ฒƒ์ธ์ง€ ๊ฒฐ์ •ํ•ด์•ผํ•จ
      • ์„œ๋ธ”๋ฆฟ์€ URL ์š”์ฒญ์„ GET, POST ๋“ฑ์˜ HTTP ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ฒ˜๋ฆฌํ•˜๋Š” ๊ตฌ์กฐ์ด๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๋Ÿฌ URL์„ ํ•˜๋‚˜์˜ ์„œ๋ธ”๋ฆฟ์—์„œ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, URL์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ์ฒ˜๋ฆฌ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์—†์Œ
      • ex1) ์–ด๋–ค ์‡ผํ•‘๋ชฐ์˜ ์ œํ’ˆ ๋“ฑ๋ก๊ณผ ์‚ญ์ œ ๊ธฐ๋Šฅ

        - ์ œํ’ˆ ๋“ฑ๋ก ์š”์ฒญ URL: /shop/addProduct
        - ์ œํ’ˆ ์‚ญ์ œ ์š”์ฒญ URL: /shop/delProduct
        
        • ์ด๋•Œ, ๋‘ URL์˜ ์š”์ฒญ์„ ํ•˜๋‚˜์˜ ์„œ๋ธ”๋ฆฟ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋„๋ก URL ๋งคํ•‘ ์„ค์ •์„ ํ•  ์ˆ˜ ์žˆ์œผ๋‚˜, ๋‘ ์š”์ฒญ ๋ชจ๋‘ GET ๋ฐฉ์‹์ด๋ผ๋ฉด URL์ด ๋‹ค๋ฅด๋”๋ผ๋„ ๋™์ผํ•œ doGet() ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋–ค ์š”์ฒญ์ด ํ˜ธ์ถœ๋œ ๊ฒƒ์ธ์ง€ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์—†์Œ
        • ๋”ฐ๋ผ์„œ ๊ฐ๊ฐ์˜ URL ์š”์ฒญ์„ ๋ณ„๋„์˜ ์„œ๋ธ”๋ฆฟ์œผ๋กœ ๊ตฌํ˜„ํ•ด์•ผ ํ•จ

        GET๋ฐฉ์‹๊ณผ POST ๋ฐฉ์‹

        • GET ๋ฉ”์„œ๋“œ๋Š” ํŠน์ • ๋ฆฌ์†Œ์Šค์˜ ํ‘œ์‹œ๋ฅผ ์š”์ฒญํ•  ๋•Œ ์‚ฌ์šฉ
        • GET์„ ์‚ฌ์šฉํ•˜๋Š” ์š”์ฒญ์€ parameter(Query String)๋ฅผ ํ†ตํ•ด ํด๋ผ์ด์–ธํŠธ์—์„œ ์ž‘์„ฑ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์„œ๋ฒ„๋กœ ์ „์†ก
        • POST ๋ฉ”์„œ๋“œ๋Š” ํŠน์ • ์„œ๋ฒ„ ๋ฆฌ์†Œ์Šค(์„œ๋ธ”๋ฆฟ ๋“ฑ)์— ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•  ๋•Œ ์‚ฌ์šฉ
        • GET ๋ฐฉ์‹๊ณผ ๋‹ฌ๋ฆฌ ์›น ๋ธŒ๋ผ์šฐ์ € ์ฃผ์†Œ์ฐฝ์— ๋ฐ์ดํ„ฐ๋Š” ๋ณด์ด์ง€ ์•Š์œผ๋ฉฐ ๋ฐ์ดํ„ฐ๋Š” Request Body์— ํฌํ•จ๋˜์–ด ์ „๋‹ฌ
        • ex2) ํšŒ์› ๊ด€๋ฆฌ ํ”„๋กœ๊ทธ๋žจ์˜ ํšŒ์› ๊ฐ€์ž…, ์Šน์ธ, ์ˆ˜์ •, ํƒˆํ‡ด(์‚ญ์ œ), ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ
        - ๊ฐ€์ž… ์–‘์‹ ํ™”๋ฉด -> ๊ฐ€์ž… ์ฒ˜๋ฆฌ ์ปจํŠธ๋กค๋Ÿฌ -> ๊ฐ€์ž… ์™„๋ฃŒํ™”๋ฉด
        - ์‹ ๊ทœ ํšŒ์› ๊ด€๋ฆฌ์ž ํ™”๋ฉด -> ์‹ ๊ทœ ํšŒ์› ๊ฐ€์ž… ์Šน์ธ ์ปจํŠธ๋กค๋Ÿฌ -> ์Šน์ธ ์™„๋ฃŒ ํ™”๋ฉด
        - ๋กœ๊ทธ์ธ ์–‘์‹ ์ž…๋ ฅ ํ™”๋ฉด -> ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ ์ปจํŠธ๋กค๋Ÿฌ -> ๋ฉ”์ธ ํ™”๋ฉด
        
        • ๊ฐ๊ฐ์˜ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์ปจํŠธ๋กค๋Ÿฌ ํ•„์š”
        • ์ž…๋ ฅ/์š”์ฒญ ํ™”๋ฉด๊ณผ ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„ ์ด๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์ปจํŠธ๋กค๋Ÿฌ, ์ฒ˜๋ฆฌ๋œ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•œ ํ™”๋ฉด ํ•„์š”
        • ๊ฐ๊ฐ์˜ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜์ง€๋งŒ, ๊ฐ™์€ ๋‹จ์œ„์˜ ์—…๋ฌด๋ฅผ ํ•˜๋‚˜์˜ ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์ฒ˜๋ฆฌํ•˜๋Š”๊ฒƒ์ด ๊ตฌ์กฐ์ ์œผ๋กœ ๊ด€๋ฆฌ๊ฐ€ ์‰ฌ์šธ ์ˆ˜ ์žˆ์Œ
          • ํ•˜๋‚˜์˜ ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์ฒ˜๋ฆฌํ•  ์š”์ฒญ์ด ์ง€๋‚˜์น˜๊ฒŒ ๋งŽ์€๊ฒฝ์šฐ ์˜คํžˆ๋ ค ์ฝ”๋“œ ๊ด€๋ฆฌ๊ฐ€ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ฃผ์˜ ํ•„์š”
      • ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ์„ ๊ตฌ๋ถ„ํ•˜์—ฌ ํ•˜๋‚˜์˜ ์„œ๋ธ”๋ฆฟ์—์„œ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๋‘๊ฐ€์ง€ ๋ฐฉ๋ฒ•
        • URL์˜ ํŒŒ๋ผ๋ฏธํ„ฐ ์ด์šฉ
          • URL์— action๊ณผ ๊ฐ™์ด ๋ณ„๋„์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋‘์–ด ์š”์ฒญ ๊ตฌ๋ถ„
          - http://xxx.com/member?action=create
          - http://xxx.com/member?action=login
          
          member: ์„œ๋ธ”๋ฆฟ URL ๋งคํ•‘ ๊ฐ’
          action: ์š”์ฒญ์„ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•œ ํŒŒ๋ผ๋ฐ‘ํ„ฐ
                  
          
          • ์š”์ฒญ์—๋Š” ํšŒ์›์ •๋ณด, ๋กœ๊ทธ์ธ ์•„์ด๋”” ๋“ฑ์˜ ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๊ฐ€ ์ถ”๊ฐ€๋กœ ํฌํ•จ
          • GET, POST ๋ฐฉ์‹์ด ๋ชจ๋‘ ๊ฐ€๋Šฅ
          • ์ปจํŠธ๋กค๋Ÿฌ์—์„œ๋Š” action๊ฐ’์„ ๋น„๊ตํ•˜์—ฌ ๋ณ„๋„์˜ ๋ฉ”์„œ๋“œ ๊ตฌํ˜„ ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌ
          • ๋น„๊ต์  ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์ด์ง€๋งŒ action ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ๊ตฌ์กฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ๊ด€๋ จ๋œ HTML,JSP,์ปจํŠธ๋กค๋Ÿฌ์˜ ์ˆ˜์ •์ด ํ•„์š”ํ•˜๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์Œ
            • URLํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ด์šฉ์˜ ์‹ค์ œ ๊ตฌํ˜„: ๋ถ„๊ธฐ๋ฌธ ์‚ฌ์šฉ
            doGet(...){
              String action = request.getParameter("action");
              switch(action){
                case "create": createMember(); break;
                case "login": loginMember(); break;
                ...
              }
            }
            
        • Front ์ปจํŠธ๋กค๋Ÿฌ ๊ตฌํ˜„
          • ๋ชจ๋“  ์š”์ฒญ์˜ ์ง„์ž…์ ์ด ๋˜๋Š” ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์„œ๋ธŒ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ตฌ์กฐ
          • ์ข€ ๋” ๋ณต์žกํ•œ ๊ตฌ์กฐ๋ฅผ ์ฒด๊ณ„์ ์œผ๋กœ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ
          • Front ์ปจํŠธ๋กค๋Ÿฌ ํŒจํ„ด์œผ๋กœ ์ •๋ฆฝ๋˜์–ด ์žˆ์–ด ์—ฌ๋Ÿฌ ๊ตฌํ˜„์— ์‘์šฉ๋˜๋Š” ๋””์ž์ธ ํŒจํ„ด
          • ๋ชจ๋“  ์š”์ฒญ์„ ํ•˜๋‚˜๋กœ ๋ชจ์œผ๋Š” ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ•˜๋ฉฐ, ์ผ๋ฐ˜์ ์œผ๋กœ ์„œ๋ธ”๋ฆฟ ๋งคํ•‘์˜ ๊ตฌ์กฐ์ ์ธ ํŠน์ง• ํ™œ์šฉ
          - http://xxx.com/member/create.do
          - http://xxx.com/member/login.do
          
          /member : ํšŒ์›๊ด€๋ฆฌ ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ context ํ˜น์€ ์„œ๋น„์Šค ๊ตฌ๋ถ„ ๊ฒฝ๋กœ
          *.do : ์„œ๋ธ”๋ฆฟ URL ๋งคํ•‘ ๊ฐ’์œผ๋กœ ๋ชจ๋“  ์š”์ฒญ์€ ํ•˜๋‚˜์˜ ์„œ๋ธ”๋ฆฟ ํ˜ธ์ถœ
          
          • ์ปจํŠธ๋กค๋Ÿฌ์—์„œ๋Š” .do ์•ž์˜ ์š”์ฒญ ์ด๋ฆ„(create, login)์œผ๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ ๋ณ„๋„์˜ ๋ฉ”์„œ๋“œ ํ˜น์€ ์„œ๋ธŒํด๋ž˜์Šค๋ฅผ ํ†ตํ•ด ์‹คํ–‰
        • Front ์ปจํŠธ๋กค๋Ÿฌ ๊ตฌํ˜„ ์žฅ์ 
          • ์š”์ฒญ์— ๋Œ€ํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ ์—†์ด ๋ช…ํ™•ํ•œ ์ด๋ฆ„(create, login)์œผ๋กœ ์š”์ฒญ
          • ์š”์ฒญ์— ๋Œ€ํ•œ URL ๊ด€๋ฆฌ๊ฐ€ ํ•„์š” ์—†์Œ
        • Front ์ปจํŠธ๋กค๋Ÿฌ ๊ตฌํ˜„ ๋‹จ์ 
          • ์ „์ฒด ์‹œ์Šคํ…œ์˜ ์„ธ๋ถ€ ์‹œ์Šคํ…œ์ด ๋ถ„๋ฆฌ๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ
            • Context๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š”๊ฒƒ์€ ์„ธ์…˜ ๊ด€๋ฆฌ ๋“ฑ์˜ ๋ถ€๋‹ด์ด ๊ฐˆ ์ˆ˜ ์žˆ์Œ
            • ex) ๋„ค์ด๋ฒ„์™€ ๊ฐ™์€ ํฌํ„ธ ํ˜•ํƒœ
          • ๋‹จ์ผ Context์— ๊ฒฝ๋กœ๋กœ ๊ตฌ๋ถ„ํ•˜๋Š” ๊ฒฝ์šฐ
            • Front ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ๋ชจ๋“  ์š”์ฒญ์„ ์กฐ๊ฑด๋ฌธ๊ณผ ๋ฉ”์„œ๋“œ ๊ตฌํ˜„๋งŒ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ์—๋Š” ์ปจํŠธ๋กค๋Ÿฌ ํด๋ž˜์Šค๊ฐ€ ๋น„๋Œ€ํ•ด์ง
          • ๊ทœ๋ชจ๊ฐ€ ์–ด๋А ์ˆ˜์ค€ ์ด์ƒ์ด ๋˜๋ฉด ๊ฒฝ๋กœ์— ๋”ฐ๋ผ ์„œ๋ธŒ ์ปจํŠธ๋กค๋Ÿฌ๋กœ ํฌ์›Œ๋”ฉ ํ•˜๋Š” ์ฒ˜๋ฆฌ ํ•„์š”
            • ์„œ๋ธŒ ์ปจํŠธ๋กค๋Ÿฌ ๊ตฌํ˜„
              • URL ์š”์ฒญ์„ ๋ถ„์„ํ•ด ์‚ฌ์šฉ์ž ์š”์ฒญ์„ ๊ตฌ๋ถ„ํ•˜๋Š” ์ž‘์—…์ด ์šฐ์„ ์ ์œผ๋กœ ํ•„์š”
              • ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด ์‚ฌ์šฉ์ž ์š”์ฒญ์„ ๋ถ„๋ฆฌํ•˜์—ฌ ์ฒ˜๋ฆฌ
                • switch(ํ˜น์€ if) ๋ฌธ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ตฌ์กฐ๋Š” ๊ธฐ๋Šฅ ์ถ”๊ฐ€ or ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•  ๋•Œ ์กฐ๊ฑด๋ฌธ๋„ ํ•จ๊ป˜ ๊ด€๋ฆฌํ•ด์•ผ ํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์Œ
                @WebServlet("*.do")
                public class MemberController extends HttpServlet{
                  ...
                  doGet(...){
                    String uri = request.getRequestURI();
                    String conPath = request.getContextPath();
                    String command = uri.substring(conPath.length());
                
                    switch(command){
                      case 'create.do': createMember(); break;
                      case 'login.do': loginMember(); break;
                    }
                  }
                }
                
                • Command ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋ฉด switch(ํ˜น์€ if) ๊ตฌ์กฐ ์—†์ด ํ•ด๋‹น ์š”์ฒญ์— ๋งž๋Š” ํŠน์ • ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์‹คํ–‰๋˜๋„๋ก ๊ตฌํ˜„
                public void init(ServletConfig sc) throws ServletException{
                  Map<String, SubController> contList = new HashMap<>();
                
                  contList.put("/create.do", new MemberCreateController());
                  contList.put("/login.do", new LoginController());
                  ...
                }
                
                public void service(HttpServletRequest request, HttpServletResponse response) throws ServletExcption, IOException{
                  String url = request.getRequestURI();
                  String contextPath = request.getContextPath();
                  String path = url.substring(contextPath.length());
                
                  SubController subController = conList.get(path);
                  subController.process(request, response);
                }
                              
                // ์„œ๋ธŒ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์šด์˜ํ•˜๋Š” Front ์ปจํŠธ๋กค๋Ÿฌ ์„ค๊ณ„
                // ์„œ๋ธŒ ์ปจํŠธ๋กค๋Ÿฌ์˜ ๊ทœ๊ฒฉ์„ ์ •์˜ํ•œ ์ธํ„ฐํŽ˜์ด์Šค ํ•„์š”
                public interface Subcontroller{
                  void process(HttpServletRequest request, HttpServletResponse response);
                }
                
                // ํ•„์š”ํ•œ ์„œ๋ธŒ ์ปจํŠธ๋กค๋Ÿฌ ๊ตฌํ˜„
                // ์œ„์˜ ๋‹ค์ค‘ ์š”์ฒญ ์ฒ˜๋ฆฌ ์„œ๋ธ”๋ฆฟ์„ ์„œ๋ธŒ ์ปจํŠธ๋กค๋Ÿฌ ๊ทœ๊ฒฉ์— ๋งž๊ฒŒ ์ˆ˜์ •
                public class MemberController implements Subcontroller{
                  void process(HttpServletRequest request, HttpServletResponse response){
                    ...
                  }
                }
                
    • ์ž…๋ ฅ ๊ฐ’ ํ•ธ๋“ค๋ง
      • ์„œ๋ธ”๋ฆฟ์—์„œ ํด๋ผ์ด์–ธํŠธ์˜ ์ž…๋ ฅ ๊ฐ’์„ ์ฒ˜๋ฆฌํ•˜๋ ค๋ฉด request.getParameter()์ด์šฉ
        • ํšŒ์›๊ฐ€์ž… ๊ฐ™์ด ์—ฌ๋Ÿฌ ์ •๋ณด๊ฐ€ ์ „๋‹ฌ๋˜๋Š” ๊ฒฝ์šฐ ๋ชจ๋“  ๊ฐ’์„ request.getParameter()๋กœ ๋ฐ›๋Š”๊ฒƒ์€ ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Œ
      • DAO ํด๋ž˜์Šค์™€ ์—ฐ๋™์„ ์œ„ํ•ด์„œ๋Š” ์ž…๋ ฅ ๊ฐ’์„ Member ๊ฐ์ฒด๋กœ ๋งŒ๋“  ํ›„์— ์ „๋‹ฌํ•ด์•ผ ํ•˜๋ฏ€๋กœ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ ๊ตฌํ˜„์ด ํ•„์š”
      doGet(...){
        Member m = new Member();
        m.setName(request.getParameter("name"));
        m.setTel(request.getParameter("tel"));
        ...
        dao.create(m);
      }
      
      • JSP์—์„œ๋Š” useBean ์•ก์…˜์„ ํ†ตํ•ด ์ž…๋ ฅ ๊ฐ’์„ Member ๊ฐ์ฒด๋กœ ์‰ฝ๊ฒŒ ์ €์žฅ ๊ฐ€๋Šฅ
      • ์„œ๋ธ”๋ฆฟ์—์„œ๋Š” ๊ทธ๋Ÿฐ ๊ธฐ๋Šฅ์ด ์ œ๊ณต๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ณ„๋„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ
      • ๋Œ€ํ‘œ์ ์œผ๋กœ Apache Commons BeanUtils ์‚ฌ์šฉ
      doGet(...){
        Member m = new Member();
        BeanUtils.populate(m, request.getParameterMap());
        ...
        dao.create(m);
      }
      
    • ๋ทฐ ์ด๋™
      • ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์‚ฌ์šฉ์ž ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•œ ๋‹ค์Œ์—๋Š” ์ ์ ˆํ•œ ๋ทฐ๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ
      • ๋ทฐ์—์„œ ๋ณด์—ฌ์ค„ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•ด์„œ ์ด๋™ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์™€ ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ๋กœ ๋‚˜๋‰จ
      • ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ
        • ์‚ฌ์šฉ์ž ์š”์ฒญ ์ฒ˜๋ฆฌ ํ›„ ๋ณ„๋„์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ํ•ด๋‹น ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋””๋ ‰์…˜(Redirection) ํ•  ์ˆ˜ ์žˆ์Œ
        • jsp, ์„œ๋ธ”๋ฆฟ ๋ชจ๋‘ response.sendRedirect()์‚ฌ์šฉ
        response.sendRedirect('main.jsp');
        
      • ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฒฝ์šฐ
        • request scope ์†์„ฑ์œผ๋กœ ๋ฐ์ดํ„ฐ ์ €์žฅ ํ›„ ์›ํ•˜๋Š” ํŽ˜์ด์ง€๋กœ forwarding
        • ๋ฐ์ดํ„ฐ ํ™œ์šฉ ๋ชฉ์ ์— ๋”ฐ๋ผ session ๋˜๋Š” applictaion์„ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์œผ๋ฉฐ ์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•˜๋Š”๊ฒƒ๋„ ๊ฐ€๋Šฅ
        doGet(...){
          ...
          request.setAttribute("member", m);
          RequestDispatcher dispatcher = request.getRequestDispatcher("userInfo.jsp");
          dispatcher.forward(request, response);
        }
        

3. [์‹ค์Šต 8-1] ์ปจํŠธ๋กค๋Ÿฌ ๊ธฐ์ดˆ ์˜ˆ์ œ: ๊ณ„์‚ฐ๊ธฐ ๊ตฌํ˜„

์ปจํŠธ๋กค๋Ÿฌ ๊ธฐ์ดˆ ์˜ˆ์ œ: ๊ณ„์‚ฐ๊ธฐ ๊ตฌํ˜„

  1. View ๊ตฌํ˜„: calForm.html, calcResult.jsp
    • calForm.html
      • ...<form method="post" action="/jwbook/calcControl" >...</form>...
    • calcResult.jsp
      • ...๊ฒฐ๊ณผ: ${result}...
  2. Model ๊ตฌํ˜„: Calculator.java
  3. Controller ๊ตฌํ˜„: CalcController.java
    • CalcController.java
      ...@WebServlet("/calcControl")
      ...request.serAttribute("result", result);
      getServletContext().getRequestDispatcher("/ch08/calcResult.jsp").forward(request,response);
    

4. [์‹ค์Šต 8-2] ๊ณ ๊ธ‰ ์ปจํŠธ๋กค๋Ÿฌ ์„œ๋ธ”๋ฆฟ ๊ตฌํ˜„

๊ณ ๊ธ‰ ์ปจํŠธ๋กค๋Ÿฌ ์„œ๋ธ”๋ฆฟ ๊ตฌํ˜„

  1. View ๊ตฌํ˜„: productList.jsp, productInfo.jsp
    • productList.jsp
     ...
     <c:forEach var="p" varStatus="i" items="${products}">
       <tr>
         <td>${i.count}</td>
         <td><a href="/jwbook/pcontrol?action=info&id=${p.id}">${p.name}</a></td>
         <td>${p.price}</td>
       </tr>
     </c:forEach>
     ...
    
    • productInfo.jsp
     ...
     <ul>
       <li>์ƒํ’ˆ์ฝ”๋“œ: ${p.id}</li>
       <li>์ƒํ’ˆ๋ช…: ${p.name}</li>
       <li>์ œ์กฐ์‚ฌ: ${p.maker}</li>
       <li>๊ฐ€๊ฒฉ: ${p.price}</li>
       <li>๋“ฑ๋ก์ผ: ${p.date}</li>
     </ul>
     ...
    
  2. Model ๊ตฌํ˜„: Product.java, ProductService.java
    • ProductService.java
     import java.util.HashMap;
     import java.util.Map;
    
     public class ProductServie{
       Map<String, Product> products = new HashMap<>();
    
       public ProductService(){
         Product p = new Product("...")
         this.products.put("101",p);
         ...
       }
       public List<Product> findAll(){
         return new ArrayList<>(products.values());
       }
       public Product find(String id){
         return products.get(id);
       }
     }
    
  3. Controller ๊ตฌํ˜„: ProdutController.java
    • ProductController.java
     @WebServlet("/pcontorl")
     public class ProductController extends HttpServlet{
       private static final long serialVersionUID = 1L;
       ProductService = service;
       ...
       public ProductController(){
         service = new ProductService();
       }
       @Override
       protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
         String action = request.getParameter("action");
         String view = "";
    
         if (request.getParameter("action") == null){
           getServletContext().getRequestDispatcher("/pcontrol?action=list").forward(request, response);
         } else{
           switch(action){
             case "list": view = list(request,response); break;
             case "info": view = info(request,response); break;
           }
           getServletContext().getRequestDispatcher("/ch08/" + view).forward(request,response);
         }
       }
    
       private String info(HttpServletRequest request, HttpServletResponse response){
         request.setAttribute("p", service.find(request.getParameter("id")));
         return "productInfo.jsp"
       }
    
       private String list(HttpServletRequest request, HttpServletResponse response){
         request.setAttribute("products", service.findAll());
         return "productList.jsp"
       }
     }  
    
    

ํƒœ๊ทธ:

์นดํ…Œ๊ณ ๋ฆฌ:

์—…๋ฐ์ดํŠธ:

๋Œ“๊ธ€๋‚จ๊ธฐ๊ธฐ