• [Spring] ๊น€์˜ํ•œ ์Šคํ”„๋ง ์ž…๋ฌธ <์„น์…˜2.์Šคํ”„๋ง ์›น ๊ฐœ๋ฐœ ๊ธฐ์ดˆ> ์ •๋ฆฌ

    2023. 10. 1.

    by. @leeeun

    ์„น์…˜2. ์Šคํ”„๋ง ์›น ๊ฐœ๋ฐœ ๊ธฐ์ดˆ

    ์›น ๊ฐœ๋ฐœ → ํฌ๊ฒŒ ์„ธ๊ฐ€์ง€ ๋ฐฉ์‹

     

    ์ •์  ์ปจํ…์ธ 

    • ์„œ๋ฒ„์—์„œ ํŒŒ์ผ์„ ๊ณ ๊ฐ(์›น ๋ธŒ๋ผ์šฐ์ €)์— ๊ทธ๋ƒฅ ์ „๋‹ฌํ•ด์ฃผ๋Š”๊ฒƒ (์„œ๋ฒ„์˜ ๋™์ž‘x)
    • ์Šคํ”„๋ง ๋ถ€ํŠธ๊ฐ€ ์ž๋™์œผ๋กœ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ
    • /resources/static์—์„œ html ํŒŒ์ผ์„ ์ฐพ์•„์„œ ๋˜์ ธ์คŒ
    • ์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ hello-static.html ์š”์ฒญ → ํ†ฐ์บฃ ์„œ๋ฒ„๊ฐ€ ์Šคํ”„๋งํ•œํ…Œ ๋„˜๊น€ → ์Šคํ”„๋ง์ด ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์šฐ์„ ์ˆœ์œ„๋กœ html์„ ์ฐพ์Œ → ๊ด€๋ จ ๋งคํ•‘๋œ ์ปจํŠธ๋กค๋Ÿฌ x → resources /static ํด๋”์˜ html์„ ์ฐพ์•„์„œ ๋ฐ˜ํ™˜

     

    MVC์™€ ํ…œํ”Œ๋ฆฟ ์—”์ง„

     

    • MVC๋ž€?
    • MVC: Model, View, Controller
    • ์„œ๋ฒ„์—์„œ html์„ ๋ณ€ํ˜•ํ•ด์„œ ๋™์ ์œผ๋กœ ๋ Œ๋”๋ง์ด ๋œ html์„ ํด๋ผ์ด์–ธํŠธ์— ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ (jsp, php๊ฐ™์€ ํ…œํ”Œ๋ฆฟ ์—”์ง„) ↔ ์ •์ ์ปจํ…์ธ  (ํŒŒ์ผ์„ ๊ทธ๋Œ€๋กœ ์ „๋‹ฌ)
    • ์š”์ฆ˜ ๋‹ค์ˆ˜ ์“ฐ๋Š” ๋ฐฉ์‹
    • ์ด์ „์—๋Š” Controller - View ๊ฐ€ ๋ถ„๋ฆฌ x (๋ชจ๋ธ1๋ฐฉ์‹) ⇒ view๋Š” ํ™”๋ฉด์„ ๊ทธ๋ฆฌ๋Š”๋ฐ ์ง‘์ค‘, ์ปจํŠธ๋กค๋Ÿฌ๋Š” ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง ๋ชจ๋ธ ํ˜น์€ ๋‚ด๋ถ€์  ์ฒ˜๋ฆฌ์— ์ง‘์ค‘, ๋ชจ๋ธ์— view์— ํ•„์š”ํ•œ ๊ฒƒ๋“ค์„ ๋‹ด์•„ view์— ๋„˜๊ฒจ์ฃผ๋Š” mvc ๋ชจ๋ธ
    • ์š”์ฆ˜์—๋Š” ๋ถ„๋ฆฌ๋˜๋Š” ๋ฐฉ์‹์ด ๊ธฐ๋ณธ์ . view๋Š” ์•ž๋‹จ, controller๋Š” ์„œ๋ฒ„ ๋’ท๋‹จ์˜ ์ผ์„ ์ฒ˜๋ฆฌ, ๋ชจ๋ธ์— ํ™”๋ฉด์— ํ•„์š”ํ•œ ๊ฒƒ๋“ค์„ ๋„˜๊ฒจ์คŒ
    • ํƒ€์ž„๋ฆฌํ”„๋Š” ํŒŒ์ผ์„ copy -> absolute pathํ•ด์„œ url์ฐฝ์— ์‹คํ–‰ํ•˜๋ฉด html ํŒŒ์ผ์„ ์„œ๋ฒ„ ์—†์ด ๋ฐ”๋กœ ์—ด์–ด๋ณผ ์ˆ˜ ์žˆ์Œ

     

    Controller

    @Controller
      public class HelloController {
          @GetMapping("hello-mvc")
          public String helloMvc(@RequestParam("name") String name, Model model) {
              model.addAttribute("name", name);
              return "hello-template";
          }
    }
    

     

     

    View

    hello! empty

    <html xmlns:th="http://www.thymeleaf.org">
    <body>
    <p th:text="'hello ' + ${name}">hello! empty</p> //hello+ name์˜ ๊ฐ’์œผ๋กœ ๋‚ด์šฉ์ด ์น˜ํ™˜์ด ๋จ. hello! empty๋Š” ๋งˆํฌ์—…ํ•˜๋Š” ๋Š๋‚Œ.
    </body>
    
    </html>

     

    ์‹คํ–‰

    • ?name= ์€ httm Get ๋ฐฉ์‹์—์„œ name ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋„˜๊ฒจ์ค„ ์ˆ˜ ์žˆ์Œ hello + ${name}์—์„œ name์˜ ๊ฐ’์— spring์„ ๋„˜๊ฒจ์คŒ
    • ๋ทฐ์—์„œ name=spring์œผ๋กœ ๋„˜๊ฒจ์คŒ → ์ปจํŠธ๋กค๋Ÿฌ์—์„œ name์ด spring์œผ๋กœ ๋ฐ”๋€Œ๊ณ  model์— ๋‹ด๊น€ → $ ์ด ํ‘œ์‹œ๊ฐ€ ๋ชจ๋ธ์—์„œ ๊ฐ’์„ ๊บผ๋‚ด๋Š” ๊ฒƒ ๋ชจ๋ธ์˜ ํ‚ค๊ฐ’์ด name์ธ ๊ฒƒ์—์„œ value๋ฅผ ๊บผ๋‚ด์„œ ์น˜ํ™˜ํ•ด์คŒ → viewResolver ๋ทฐ๋ฅผ ์ฐพ์•„์ฃผ๊ณ  ํ…œํ”Œ๋ฆฟ์„ ์—ฐ๊ฒฐํ•ด์ฃผ๋Š” ํ•ด๊ฒฐ์ž๊ฐ€ ํ…œํ”Œ๋ฆฟ์˜ hello-template์„ ์ฐพ์•„์„œ ํ…œํ”Œ๋ฆฟ์—”์ง„์— ๋„˜๊ฒจ์คŒ → ํƒ€์ž„๋ฆฌํ”„ ํ…œํ”Œ๋ฆฟ ์—”์ง„์ด ๋ Œ๋”๋ง์„ ํ•ด์„œ ๋ณ€ํ™˜์„ ํ•œ html์„ ์›น ๋ธŒ๋ผ์šฐ์ €์— ๋ฐ˜ํ™˜ (์ •์  ์ปจํ…์ธ ์™€์˜ ์ฐจ์ด์ )

     

    API

    • ๋ฆฌ์•กํŠธ์˜ ์‚ฌ์šฉ, ์„œ๋ฒ„๋ผ๋ฆฌ์˜ ํ†ต์‹  ๋“ฑ ๋ฐ์ดํ„ฐ๊ฐ€ ํ๋ฅผ ๋•Œ
    • ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ. HttpMessageConverter๋ฅผ ํ†ตํ•ด JSONํฌ๋งท์œผ๋กœ ๋ฐ˜ํ™˜. view ์—†์ด HTTP response์— ๊ฐ’์„ ๋„ฃ์–ด ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ
    • ์•ˆ๋“œ๋กœ์ด๋“œ, ์•„์ดํฐ ํด๋ผ์ด์–ธํŠธ์™€ ๊ฐœ๋ฐœ์„ ํ•ด์•ผํ•  ๋•Œ) JSON ๋ฐ์ดํ„ฐ ํฌ๋งท์„ ์‚ฌ์šฉ. JSON ํฌ๋งท์œผ๋กœ ์ „๋‹ฌํ•ด์ฃผ๋Š” ๋ฐฉ์‹

     

    @ResponseBody ๋ฌธ์ž ๋ฐ˜ํ™˜

    @Controller
      public class HelloController {
    		@GetMapping("hello-string")
        @ResponseBody //http์˜ body๋ถ€์— return ๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ ๋„ฃ๊ฒ ๋‹ค๋Š” ์ด์•ผ๊ธฐ. spring์œผ๋กœ name์„ ๋„ฃ์œผ๋ฉด
        public String helloString(@RequestParam("name") String name){
            return "hello"+name; //hello spring์œผ๋กœ ๋ฐ”๋€œ. ํ…œํ”Œ๋ฆฟ์—”์ง„๊ณผ ๋‹ค๋ฅด๊ฒŒ view๊ฐ€ ์—†๊ณ  ๋ฌธ์ž๊ฐ€ ํด๋ผ์ด์–ธํŠธ์— ๊ทธ๋Œ€๋กœ ๋‚ด๋ ค๊ฐ.
        } //view ์—†์ด ๋ฌธ์ž๋ฅผ ๊ทธ๋Œ€๋กœ ๋‚ด๋ ค์ฃผ๋Š” ๋ฐฉ์‹ (๊ฑฐ์˜ ์“ธ ์ผ ์—†์Œ)
    }
    
    • view ์—†์ด ๋ฌธ์ž๋ฅผ ๊ทธ๋Œ€๋กœ ๋‚ด๋ ค์ฃผ๋Š” ๋ฐฉ์‹ (๊ฑฐ์˜ ์“ธ ์ผ ์—†์Œ)
    • ๋ทฐ ๋ฆฌ์กธ๋ฒ„( viewResolver )๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ
    • ๋Œ€์‹ ์— HTTP์˜ BODY์— ๋ฌธ์ž ๋‚ด์šฉ์„ ์ง์ ‘ ๋ฐ˜ํ™˜(HTML BODY TAG๋ฅผ ๋งํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹˜)

     

    @ResponseBody ๊ฐ์ฒด ๋ฐ˜ํ™˜

    @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; //key๊ฐ€ name
    
            public String getName() { //๊บผ๋‚ผ๋•Œ
                return name;
            }
    
            public void setName(String name) { //๋„ฃ์„๋•Œ
                this.name = name;
            }
    }
    
    • @ResponseBody ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด ๊ฐ์ฒด๊ฐ€ JSON์œผ๋กœ ๋ณ€ํ™˜๋จ

    • HTTP์˜ BODY์— ๋ฌธ์ž ๋‚ด์šฉ์„ ์ง์ ‘ ๋ฐ˜ํ™˜
      • ์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ hello-api ์š”์ฒญ → ํ†ฐ์บฃ ์„œ๋ฒ„๊ฐ€ ์Šคํ”„๋ง์— ๋„˜๊น€ → helloController์— hello-api๊ฐ€ ์žˆ์ง€๋งŒ ResponseBody ์–ด๋…ธํ…Œ์ด์…˜ ํ™•์ธ → ์–ด๋…ธํ…Œ์ด์…˜์ด ์—†์œผ๋ฉด viewresolver๊ฐ€ html์„ ๋˜์ ธ์ฃผ๋Š”๋ฐ,
      • ResoponseBody๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๋ฌธ์ž๊ฐ€ ์•„๋‹Œ ๊ฐ์ฒด์ธ ๊ฒฝ์šฐ HttpMessageConverter ์ค‘ JsonConverter๊ฐ€ ๋™์ž‘ → ๋””ํดํŠธ๋กœ JSON ๋ฐฉ์‹์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋งŒ๋“ค์–ด์„œ HTTP์˜ ์‘๋‹ต์— ์š”์ฒญํ•œ ์ฃผ์ฒด๋กœ ๋ฐ˜ํ™˜
    • HTTP Accept Header์—์„œ ์š”์ฒญ์„ ํ•  ๋•Œ ์ด๋Ÿฐ ํฌ๋งท์œผ๋กœ ๋ฐ›๊ณ  ์‹ถ๋‹ค~ ์—ฌ๊ธฐ์„œ ํฌ๋งท์„ ์ง€์ •ํ•˜๋ฉด ์ง€์ •๋œ ๊ฑธ๋กœ ๋ณด๋‚ด๊ณ (์ด์— ํ•ด๋‹นํ•˜๋Š” ๋ฉ”์„ธ์ง€ ์ปจ๋ฒ„ํ„ฐ๊ฐ€ ๋™์ž‘), ํฌ๋งท์„ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ์Šคํ”„๋ง์ด ์•Œ์•„์„œ ๋ณด๋ƒ„

     

    • viewResolver ๋Œ€์‹ ์— HttpMessageConverter ๊ฐ€ ๋™์ž‘
      • ๊ธฐ๋ณธ ๋ฌธ์ž์ฒ˜๋ฆฌ: StringHttpMessageConverter
      • ๊ธฐ๋ณธ ๊ฐ์ฒด์ฒ˜๋ฆฌ: MappingJackson2HttpMessageConverter
      • byte ์ฒ˜๋ฆฌ ๋“ฑ๋“ฑ ๊ธฐํƒ€ ์—ฌ๋Ÿฌ HttpMessageConverter๊ฐ€ ๊ธฐ๋ณธ์œผ๋กœ ๋“ฑ๋ก๋˜์–ด ์žˆ์Œ

    ์ฐธ๊ณ ) ํด๋ผ์ด์–ธํŠธ์˜ HTTP Accept ํ•ด๋”์™€ ์„œ๋ฒ„์˜ ์ปจํŠธ๋กค๋Ÿฌ ๋ฐ˜ํ™˜ ํƒ€์ž… ์ •๋ณด ๋‘˜์„ ์กฐํ•ฉํ•ด์„œ HttpMessageConverter ๊ฐ€ ์„ ํƒ๋จ.

    • Gson, Jackson(์Šคํ”„๋ง์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ํƒ‘์žฌ)→ ๊ฐ์ฒด๋ฅผ JSON์œผ๋กœ ๋ฐ”๊ฟ”์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค

     

     

    ๋” ์•Œ์•„๋ณผ ๊ฒƒ

    • JSON vs xml

    xml → html์˜ ํƒœ๊ทธ ๋ฐฉ์‹ ๋ฌด๊ฒ๊ณ , ์—ด๊ณ  ๋‹ซ๊ณ ๋ฅผ ๋‘๋ฒˆ ์จ์•ผ ํ•˜๊ณ …spring๋„ ResoponseBody์—์„œ json์œผ๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ด ๋””ํดํŠธ (๋ ˆ๊ฑฐ์‹œ ํ”„๋กœ์ ํŠธ๋‚˜ xml..)

    ์ตœ๊ทผ์—๋Š” ๊ฑฐ์˜ JSON ๋ฐฉ์‹์œผ๋กœ ํ†ต์ผ ⇒ ๊ทธ๋ƒฅ json์œผ๋กœ ํ•˜๋ฉด ๋จ

    {key:value} ํ˜•ํƒœ → simpleํ•œ ํ˜•ํƒœ

     

    • Java bin ํ‘œ์ค€ ๋ฐฉ์‹ ⇒ private์ด๋ผ ๋ฐ”๋กœ ๋ชป ๊บผ๋‚ด๊ณ  ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด์„œ ์ ‘๊ทผ.
    • property ์ ‘๊ทผ๋ฐฉ์‹ getter setter

     

     

    ์œ ์šฉํ•œ ๋‹จ์ถ•ํ‚ค

    command+shift+enter ํ•˜๋ฉด ; ์น˜๊ณ  ์—”ํ„ฐ ์•ˆ์ณ๋„ ๊ทธ๋ƒฅ ์™„์„ฑ์‹œ์ผœ์คŒ

    control+enter : generate ๋‹จ์ถ•ํ‚ค

    command+p ํŒŒ๋ผ๋ฏธํ„ฐ ์ •๋ณด

     

     

    * ์ด ํฌ์ŠคํŠธ๋Š” ์ธํ”„๋Ÿฐ์˜ ๊น€์˜ํ•œ ์Šคํ”„๋ง ์ž…๋ฌธ ๊ฐ•์ขŒ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.*

    https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8

    ๋Œ“๊ธ€