๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐ŸŒฟ Spring

[์ž…๋ฌธ] ์›น ๊ฐœ๋ฐœ ๊ธฐ์ดˆ - ์ •์  ์ปจํ…์ธ , MVC์™€ ํ…œํ”Œ๋ฆฟ ์—”์ง„, API

by nitronium102 2021. 6. 29.

ํฌ๊ฒŒ ์„ธ ์ข…๋ฅ˜๊ฐ€ ์žˆ๋‹ค.

01. ์ •์  ์ปจํ…์ธ  : ํŒŒ์ผ์„ ์›น ๋ธŒ๋ผ์šฐ์ €์— ๊ทธ๋ƒฅ ์ „๋‹ฌํ•ด์ค€๋‹ค.

02 MVC & ํ…œํ”Œ๋ฆฟ ์—”์ง„ : ์„œ๋ฒ„์—์„œ HTML์„ ์กฐ๊ธˆ ๋ฐ”๊ฟ”์„œ ์ „๋‹ฌํ•ด์ค€๋‹ค

03. API : json ๋ฐ์ดํ„ฐ ํฌ๋งท์œผ๋กœ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ฐ์ดํ„ฐ ์ „๋‹ฌ / ์„œ๋ฒ„๋ผ๋ฆฌ ํ†ต์‹ ํ•  ๋•Œ๋„ ์‚ฌ์šฉ

 

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

- ์Šคํ”„๋ง๋ถ€ํŠธ์—์„œ ์ •์  ์ปจํ…์ธ ๋ฅผ ์ง€์›ํ•œ๋‹ค.

https://docs.spring.io/spring-boot/docs/2.3.1.RELEASE/reference/html/spring-boot-features.html#boot-features-spring-mvc-static-content

 

Spring Boot Features

Graceful shutdown is supported with all four embedded web servers (Jetty, Reactor Netty, Tomcat, and Undertow) and with both reactive and Servlet-based web applications. It occurs as part of closing the application context and is performed in the earliest

docs.spring.io

์ •์  ์ปจํ…์ธ  ๋™์ž‘ ์›๋ฆฌ

01. ์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ localhost์— ์ ‘์† ์š”์ฒญ์„ ๋ณด๋‚ธ๋‹ค.

02. ๋‚ด์žฅ ํ†ฐ์บฃ ์„œ๋ฒ„๊ฐ€ ์š”์ฒญ์„ ๋ฐ›์•„ hello-static์„ ํ™•์ธํ•œ ํ›„ ์Šคํ”„๋ง์œผ๋กœ ๋ณด๋‚ธ๋‹ค.

03. ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ํ™•์ธํ•œ๋‹ค(์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์šฐ์„  ์ˆœ์œ„๋ฅผ ๊ฐ€์ง„๋‹ค) -> ๊ทผ๋ฐ ๊ด€๋ จ ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์—†๋‹ค

04. resources/static ๋‚ด๋ถ€์— ๋™์ผ ์ด๋ฆ„์„ ๊ฐ€์ง„ ํŒŒ์ผ์ด ์žˆ๋Š”์ง€ ์ฐพ์•„๋ณธ๋‹ค.

05. ์žˆ์œผ๋ฉด ๋ฐ˜ํ™˜ํ•œ๋‹ค. 

 

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

MVC๋ž€?

Model, View, Controller๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค. ์›๋ž˜๋Š” view๋ž‘ controller๋ฅผ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š์•˜์ง€๋งŒ ์œ ์ง€๋ณด์ˆ˜๋ฅผ ์šฉ์ดํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ๋ถ„๋ฆฌํ•˜์—ฌ ํ˜„์žฌ์˜ ํ˜•ํƒœ๊ฐ€ ๋˜์—ˆ๋‹ค!

 

Controller

@Controller
public class HelloController {
    @GetMapping("hello-mvc")
    public String helloMvc(@RequestParam(value="name") String name, Model model){ // ์™ธ๋ถ€์—์„œ ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฐ›๋Š”๋‹ค
        model.addAttribute("name", name); // ์•ž์—๊ฐ€ key ๋’ค์—๊ฐ€ value
        return "hello-template";
    }
}

- ์ฐธ๊ณ ๋กœ ์—ฌ๊ธฐ์—์„œ ํ™ˆํŽ˜์ด์ง€ ์ฃผ์†Œ๋Š” localhost:8080/hello-mvc์ด๋‹ค! (hello-template ์•„๋‹˜)

localhost:8080/hello-mvc๋กœ ๋“ค์–ด๊ฐ€๋ฉด error๊ฐ€ ๋œจ๋Š”๋ฐ name ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋„˜๊ฒจ์ฃผ์ง€ ์•Š์•„์„œ ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ์ด๋‹ค

์œ„ ์ฝ”๋“œ์— name์—์„œ ctrl+P(์œˆ๋„์šฐ ๊ธฐ์ค€)์„ ๋ˆ„๋ฅด๋ฉด ์˜ต์…˜์ด ๋‚˜ํƒ€๋‚˜๋Š”๋ฐ, required๋ฅผ false๋กœ ์ง€์ •ํ•ด์ฃผ๋ฉด ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์•ˆ ๋„˜๊ฒจ๋„ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์œ„์™€ ๊ฐ™์€ ์˜ค๋ฅ˜๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ๋‹ค(required๋Š” default true)

ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๋Š” name์„ ๋ฐ›์•„์•ผ ํ•˜๋ฏ€๋กœ...์‚ฌ์ดํŠธ ์ฃผ์†Œ์— ์ง์ ‘ name์„ ๋„ฃ์–ด์ฃผ์ž

์„ฑ๊ณต

 

MVC, ํ…œํ”Œ๋ฆฟ ์—”์ง„ ์ž‘๋™ ์›๋ฆฌ

01. ์›น ๋ธŒ๋ผ์šฐ์ € -> ํ†ฐ์บฃ ์„œ๋ฒ„ -> ์Šคํ”„๋ง

02. helloController์— ๋ฉ”์†Œ๋“œ๊ฐ€ mapping ๋˜์–ด์žˆ์œผ๋ฏ€๋กœ ํ•ด๋‹น ์กฐ๊ฑด์— ๋”ฐ๋ผ ์Šคํ”„๋ง์— ๋„˜๊ฒจ์ค€๋‹ค

03. viewResolver๊ฐ€ view๋ฅผ ์ฐพ์•„์ฃผ๊ณ  ํ…œํ”Œ๋ฆฟ ์—”์ง„์„ ์—ฐ๊ฒฐํ•ด์ค€๋‹ค. -> template์—์„œ ์ฐพ์•„์„œ ๋„˜๊ฒจ์ค€๋‹ค. 

04. ํ…œํ”Œ๋ฆฟ ์—”์ง„์ด ๋ Œ๋”๋ง์„ ํ•˜์—ฌ(์ •์  ๋ธŒ๋ผ์šฐ์ €์™€์˜ ์ฐจ์ด์ ) ์›น ๋ธŒ๋ผ์šฐ์ €์— ๋„˜๊ฒจ์ค€๋‹ค

 

API

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

@Controller public class HelloController {
	@GetMapping("hello-string") 
    @ResponseBody 
    public String helloString(@RequestParam("name") String name) { 
    	return "hello " + name; 
    }
 }

@ResponseBody ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ทฐ ๋ฆฌ์กธ๋ฒ„( viewResolver )๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค - ํ…œํ”Œ๋ฆฟ ์—”์ง„๊ณผ์˜ ์ฐจ์ด์ !!

๋Œ€์‹ ์— HTTP์˜ BODY์— ๋ฌธ์ž ๋‚ด์šฉ์„ ์ง์ ‘ ๋ฐ˜ํ™˜(HTML BODY TAG๋ฅผ ๋งํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹˜)

- ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด HTML์—†์ด ๋ƒ…๋‹ค hello name๋งŒ ๋‚˜์˜จ๋‹ค

 

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

  @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;

		// property ์ ‘๊ทผ ๋ฐฉ์‹(JavaBean)
        public String getName() {
            return name;
        }

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

http://localhost:8080/hello-api?name=spring

์‹คํ–‰ํ•˜๋ฉด JSON ํ˜•ํƒœ์˜ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜จ๋‹ค.

๊ธฐ์กด์˜ xml ๋ฐฉ์‹์€ ์—ด๊ณ  ๋‹ซ์•„์•ผ ํ–ˆ๋Š”๋ฐ json์€ ๋ฐ”๋กœ ๋‚˜์˜ค๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ„๋‹จํ•˜๋‹ค. ์ตœ๊ทผ์—๋Š” ๊ฑฐ์˜ JSON ๋ฐฉ์‹์œผ๋กœ ๊ฐ€๊ณ  ์žˆ๋‹ค. 

 

@ResponseBody ์ž‘๋™์›๋ฆฌ

01. ๋ธŒ๋ผ์šฐ์ € -> ํ†ฐ์บฃ -> ์Šคํ”„๋ง

02. helloapi Controllerํ™•์ธ -> @ResponseBody annotation ํ™•์ธ -> http์— ๊ทธ๋ƒฅ ๋ฐ์ดํ„ฐ๋ฅผ ๋„˜๊ธฐ์ž!

๊ทผ๋ฐ ๋ฌธ์ž๊ฐ€ ์•„๋‹ˆ๊ณ  ๊ฐ์ฒด์ด๋‹ค? default JSON ๋ฐฉ์‹์œผ๋กœ ๋ฐ˜ํ™˜ํ•˜์ž

  • HTTP์˜ BODY์— ๋ฌธ์ž ๋‚ด์šฉ์„ ์ง์ ‘ ๋ฐ˜ํ™˜
  • viewResolver ๋Œ€์‹  HttpMessageConverter๊ฐ€ ๋™์ž‘ํ•œ๋‹ค
  • ๊ธฐ๋ณธ ๋ฌธ์ž ์ฒ˜๋ฆฌ : StringHttpMessageConverter
  • ๊ธฐ๋ณธ ๊ฐ์ฒด ์ฒ˜๋ฆฌ : MappingJackson2HttpMessageConverter (Jackson - JSON์œผ๋กœ ๋ฐ”๊ฟ”์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ)
  • byte ์ฒ˜๋ฆฌ ๋“ฑ ๊ธฐํƒ€ ์—ฌ๋Ÿฌ HttpMessageConverter๊ฐ€ ๊ธฐ๋ณธ์œผ๋กœ ๋“ฑ๋ก๋˜์–ด ์žˆ์Œ
์ฐธ๊ณ  : ํด๋ผ์ด์–ธํŠธ์˜ HTTP Accept ํ—ค๋”์™€ ์„œ๋ฒ„์˜ ์ปจํŠธ๋กค๋Ÿฌ ๋ฐ˜ํ™˜ ํƒ€์ž… ์ •๋ณด ๋‘˜์„ ์กฐํ•ฉํ•ด์„œ HttpMessageConverter๊ฐ€ ์„ ํƒ๋œ๋‹ค. 


์˜ค๋Š˜์˜ ํŒโœจ

Ctrl+shift+enter๋ฅผ ๋ˆ„๋ฅด๋ฉด ๋๊นŒ์ง€ ์ž๋™์™„์„ฑํ•ด์ค€๋‹ค

๋Œ“๊ธ€