๐Ÿ’ป ์ฝ”๋”ฉ ์ผ๊ธฐ : [Spring] 'Spring MVC' ํŽธ

ybkยท2024๋…„ 4์›” 9์ผ

spring

๋ชฉ๋ก ๋ณด๊ธฐ
6/55
post-thumbnail

๐Ÿ”” 'Spring MVC'์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์ž!


๐Ÿ’Ÿ Spring MVC

  • Controller๋Š” ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์— ๋”ฐ๋ผ ์„œ๋ฒ„์—์„œ ์ด๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
  • Model์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
  • View๋Š” ํ™”๋ฉด์„ ๋‹ด๋‹นํ•˜๋Š” ๋ทฐ ํ…œ๋ธ”๋ฆฟ์ž…๋‹ˆ๋‹ค.

์›นํŽ˜์ด์ง€๋ฅผ ํ™”๋ฉด์— ๋ณด์—ฌ์ฃผ๊ณ  ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์—ญํ•˜๋ฅผ ๋‚˜๋ˆ„๋Š” ๊ธฐ๋ฒ•์ด MVC ํŒจํ„ด์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

๐ŸŸฆ MVC(Model-View-Controller) ํŒจํ„ด์˜ ์ž‘๋™ ๊ณผ์ •

ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์„ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•˜์—ฌ view๋กœ ์‘๋‹ตํ•˜๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค.

  1. Controller:

    • ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ๋ฐ›์•„๋“ค์—ฌ ๋ถ„์„ํ•˜๊ณ  ๊ฐ€๊ณตํ•ฉ๋‹ˆ๋‹ค.
    • ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์‹คํ–‰ํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
    • ๊ฒฐ๊ณผ๋ฅผ ๋ชจ๋ธ์— ๋‹ด์Šต๋‹ˆ๋‹ค.
    • ๊ฒฐ๊ณผ๋ฅผ ๋ณด์—ฌ์ค„ view์˜ ์ด๋ฆ„์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.(view๋กœ ํฌ์›Œ๋”ฉ)
  2. Model:

    • Controller์—์„œ ์ฒ˜๋ฆฌํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.
  3. View:

    • Controller๊ฐ€ ๋ฐ˜ํ™˜ํ•œ ๋ชจ๋ธ์„ ๊ธฐ๋ฐ˜์œผ๋กœ HTML์„ ์™„์„ฑํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.
    • Model์— ๋‹ด๊ธด ๊ฐ’์„ ๊บผ๋‚ด HTML์„ ์ƒ์„ฑํ•˜๊ณ , ์ด๋ฅผ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์‘๋‹ตํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๊ณผ์ •์„ ํ†ตํ•ด ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ๋ฐ›์•„๋“ค์—ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์‹คํ–‰ํ•˜๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ณด์—ฌ์ฃผ๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์—์„œ Controller๋Š” ์š”์ฒญ์„ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•˜๊ณ , View๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•˜๋ฉฐ, Model์€ Controller์™€ View ๊ฐ„์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

  • jsp๋Š” html ์ฝ”๋“œ๋กœ ์ƒ๊ฒผ์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” java ์ฝ”๋“œ๋กœ ๋ณ€ํ™˜๋˜์–ด OutputStream์˜ write() ๋ฉ”์†Œ๋“œ์— ์˜ํ•ด HTML ์ฝ”๋“œ๊ฐ€ ์ƒ์„ฑํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ๋กœ ๋ณด๋‚ด์ง‘๋‹ˆ๋‹ค.

๐Ÿ’Ÿ View

view๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•

import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import java.io.IOException;

@Controller
@RequestMapping("main7")
public class Controller07 {

    // /main7/sub5
    // ์š”์ฒญ ๊ฒฝ๋กœ์™€ view ์ด๋ฆ„์ด ๊ฐ™์€ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค
    @RequestMapping("sub5")
    public String method5() {
        return "main7/sub5";
    }

    @RequestMapping("sub6")
    public String method6() {
        // ์š”์ฒญ ๊ฒฝ๋กœ์™€ ๊ฐ™์€ view ์ด๋ฆ„์œผ๋กœ ๊ฒฐ์ •๋จ
        return null;
    }

    @RequestMapping("sub7")
    public void method7() {
        // ์š”์ฒญ ๊ฒฝ๋กœ์™€ ๊ฐ™์€ view์˜ ์ด๋ฆ„์œผ๋กœ ๊ฒฐ์ •๋˜์–ด
        // ๋ฆฌํ„ด์„ ์•ˆํ•ด๋„ ๋จ
        // view : /WEB-INF/view/main7/sub7.jsp
    }

}
  1. method5():

    • ์ด ๋ฉ”์†Œ๋“œ๋Š” "main7/sub5"์™€ ๊ฐ™์€ ๋ทฐ ์ด๋ฆ„์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    • ์ด ๊ฒฝ์šฐ, ๋ฐ˜ํ™˜๋œ ๋ทฐ ์ด๋ฆ„์€ URI์™€ ์ผ์น˜ํ•˜๋Š” JSP ํŒŒ์ผ์„ ์ฐพ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
    • ์˜ˆ๋ฅผ ๋“ค์–ด, "main7/sub5"๊ฐ€ ๋ฐ˜ํ™˜๋˜๋ฉด ViewResolver๋Š” "/WEB-INF/view/main7/sub5.jsp"๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.
  2. method6():

    • ์ด ๋ฉ”์†Œ๋“œ๋“ค์€ ๋ฌธ์ž์—ด "null" ๋˜๋Š” void๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    • ๋ฐ˜ํ™˜๊ฐ’์ด ์—†๋Š” ๊ฒฝ์šฐ, Spring์€ ์š”์ฒญ ๊ฒฝ๋กœ์— ๋”ฐ๋ผ ๋ทฐ๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.
    • ์˜ˆ๋ฅผ ๋“ค์–ด, "main7/sub6"์ด ์š”์ฒญ๋œ ๊ฒฝ์šฐ, ViewResolver๋Š” "/WEB-INF/view/main7/sub6.jsp"๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.
    • ๋ฉ”์†Œ๋“œ ๋‚ด์—์„œ ๋ช…์‹œ์ ์œผ๋กœ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š์•„๋„ ๋ฉ๋‹ˆ๋‹ค.
  3. method7():

    • ์ด ๋ฉ”์†Œ๋“œ๋Š” void๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ, ์•„๋ฌด๋Ÿฐ ์ž‘์—…์„ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
    • ์ด ๊ฒฝ์šฐ์—๋„ ์š”์ฒญ ๊ฒฝ๋กœ์— ๋”ฐ๋ผ ๋ทฐ๊ฐ€ ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค.
    • ๋ฐ˜ํ™˜๊ฐ’์ด ์—†๋Š” ๊ฒฝ์šฐ์—๋„ ์ปจํŠธ๋กค๋Ÿฌ ๋‚ด์—์„œ ๋ทฐ ๊ฒฐ์ • ๋กœ์ง์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์š”์•ฝํ•˜๋ฉด, ์ปจํŠธ๋กค๋Ÿฌ ๋ฉ”์†Œ๋“œ๋Š” ๋‹ค์–‘ํ•œ ๋ฐฉ์‹์œผ๋กœ ๋ทฐ๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” Spring MVC๊ฐ€ ์œ ์—ฐํ•˜๊ฒŒ ๋ทฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์š”์ฒญ ๊ฒฝ๋กœ์™€ ๋ทฐ ์ด๋ฆ„ ์‚ฌ์ด์˜ ๋งคํ•‘์€ ViewResolver์— ์˜ํ•ด ๊ด€๋ฆฌ๋˜๋ฉฐ, ์ปจํŠธ๋กค๋Ÿฌ์˜ ๋ฐ˜ํ™˜ ๊ฐ’์— ๋”ฐ๋ผ ์ด ๋งคํ•‘์ด ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.


๐Ÿ’Ÿ Model

  • ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๋Š” ์ปจํ…Œ์ด๋„ˆ ์—ญํ• ์„ ํ•˜๋ฉฐ, ์ฃผ๋กœ ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ๋ทฐ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • name๊ณผ value ์Œ์œผ๋กœ ์กด์žฌํ•˜๋ฉฐ(entry) Map๊ณผ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ๋•Œ๋Š” addAttribute() ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ €์žฅํ•˜๊ณ , ๋ทฐ์—์„œ๋Š” ${attribute๋ช…}์„ ์ž‘์„ฑํ•˜๋ฉด ํ•ด๋‹น attribute๋ช…์— ๋งคํ•‘๋œ attribute value๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.
  • model Attribute์˜ name์€ String ํƒ€์ž…์ด๋ฉฐ, model Attribute์˜ value : Object ํƒ€์ž…์ด๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋–ค ํƒ€์ž…์˜ ๋ฐ์ดํ„ฐ๋“ ์ง€ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๋ฐ์ดํ„ฐ ํƒ€์ž…์œผ๋กœ๋Š” String, ๊ธฐ๋ณธ ์ž๋ฃŒํ˜•(wrapper), ๋ฐฐ์—ด, List, Map, JavaBeans ๋“ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

String

@RequestMapping("sub2")
public void method2(Model model) {
    model.addAttribute("city", "์„œ์šธ");
    model.addAttribute("address", "์‹ ์ดŒ");
}
<body>
<h1> ๋„์‹œ๋Š” '${city}' ์ž…๋‹ˆ๋‹ค.</h1>
<h1> ์ฃผ์†Œ๋Š” '${address}' ์ž…๋‹ˆ๋‹ค.</h1>
</body>

๋ฐฐ์—ด

@RequestMapping("sub5")
public void method5(Model model) {
    model.addAttribute("cities", new String[]{"์„œ์šธ", "๋Œ€๊ตฌ", "๋ถ€์‚ฐ"});
    model.addAttribute("countries", new String[]{"ํ•œ๊ตญ", "๋ฏธ๊ตญ", "์ผ€๋ƒ"});

}
<body>
<h1>${cities[0]}, ${cities[1]}, ${cities[2]}</h1>
<h1>${countries[0]}, ${countries[1]}, ${countries[2]}</h1>
</body>

List

@RequestMapping("sub6")
public void method6(Model model) {
    List<String> data = List.of("java", "css", "html", "jsp");
    model.addAttribute("myList", data);
}
<body>
<h1>${myList}</h1>
<h1>${myList[0]}</h1>
<h1>${myList[1]}</h1>
<h1>${myList[2]}</h1>
<h1>${myList[3]}</h1>
</body>

Map

@RequestMapping("sub9")
public void method9(Model model) {
    Map<String, String> map = new HashMap<>();
    map.put("name", "ํฅ๋ฏผ");
    map.put("age", "์„œ๋ฅธ");
    map.put("address", "๋Ÿฐ๋˜");

    model.addAttribute("myMap", map);
}
<body>
<h1>${myMap["name"]}</h1>
<h1>${myMap["age"]}</h1>
<h1>${myMap["address"]}</h1>
<hr>
<%-- attributeName.key --%>

<h1>${myMap.name}</h1>
<h1>${myMap.age}</h1>
<h1>${myMap.address}</h1>
</body>
  • ๋งŒ์•ฝ ํ•œ๊ธ€์ด๊ฑฐ๋‚˜ ํŠน์ˆ˜๊ธฐํ˜ธ์ผ ๋•Œ๋Š” myMap["ํ‚ค"]๋กœ ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

JavaBeans

JavaBeans๋Š” ์ž๋ฐ” ์–ธ์–ด์˜ ์ผ๋ฐ˜์ ์ธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ด€๋ก€์— ๋”ฐ๋ผ ์ž‘์„ฑ๋œ ์ž๋ฐ” ํด๋ž˜์Šค(์ž๋ฐ” ๊ฐ์ฒด)์ž…๋‹ˆ๋‹ค.

  • ํ”„๋กœํผํ‹ฐ(๋ฉค๋ฒ„ ๋ณ€์ˆ˜)๋ฅผ ํฌํ•จํ•˜๋ฉฐ, ์ด ํ”„๋กœํผํ‹ฐ๋“ค์€ private์œผ๋กœ ์„ ์–ธ๋˜์–ด ์™ธ๋ถ€์—์„œ ์ง์ ‘ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋Œ€์‹ ์— getter์™€ setter ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค.
  • ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†๋Š” ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•จ์œผ๋กœ์จ JavaBeans๋ฅผ ๋‹ค๋ฅธ ํด๋ž˜์Šค์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
public class MyBean094 {
    private String modelNumber;
    private Integer productPrice;
    private String name;
    private Double weight;
    private boolean used;

    public String getModelNumber() {
        return modelNumber;
    }

    public void setModelNumber(String modelNumber) {
        this.modelNumber = modelNumber;
    }

    public Integer getProductPrice() {
        return productPrice;
    }

    public void setProductPrice(Integer productPrice) {
        this.productPrice = productPrice;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getWeight() {
        return weight;
    }

    public void setWeight(Double weight) {
        this.weight = weight;
    }

    public boolean isUsed() {
        return used;
    }

    public void setUsed(boolean used) {
        this.used = used;
    }
}
@RequestMapping("sub4")
public void sub4(Model model) {
    MyBean094 myBean094 = new MyBean094();
    myBean094.setModelNumber("k5");
    myBean094.setProductPrice(5000);
    myBean094.setName("kia");
    myBean094.setWeight(2400.50);
    myBean094.setUsed(true);

    model.addAttribute("car", myBean094);
}
<body>
<h1>${car.modelNumber}</h1>
<h1>${car.productPrice}</h1>
<h1>${car.name}</h1>
<h1>${car.weight}</h1>
<h1>${car.used}</h1>
</body>
profile
๊ฐœ๋ฐœ์ž ์ค€๋น„์ƒ~

0๊ฐœ์˜ ๋Œ“๊ธ€