Spring MVC๋ ๋ฌด์์ธ๊ฐ?
MVC ๋์์ธ ํจํด
๋์์ธ ํจํด: ํจ์จ์ ์ธ ๋ฐฉ๋ฒ๋ค์ ํจํดํ ํด๋์ ๊ฒ
MVC๋ ์ํํธ์จ์ด ๋์์ธ ํจํด ์ค ํ๋๋ก, ์ํํธ์จ์ด๋ฅผ ๊ตฌ์ฑํ๋ ์์๋ค์ Model-View-Controller๋ก ๊ตฌ๋ถํด ๊ฐ๊ฐ์ ์ญํ ์ ๋ถ๋ฆฌ
→ ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ ๋์ด๊ณ , ๊ฐ๋ฐ์๋ค ๊ฐ์ ํ์ ์ ์ฉ์ดํ๊ฒ ํจ
- Model: ๋ฐ์ดํฐ์ ๋น์ฆ๋์ค ๋ก์ง ๋ด๋น
- ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๋
- ๋ฐ์ดํฐ ์ ์ฅ, ์กฐํ
- View: ์ฌ์ฉ์ ์ธํฐํ์ด์ค ๋ด๋น
- ์ฌ์ฉ์๊ฐ ๋ณด๋ ํ๋ฉด์ด๋ ๋ฒํผ ํผ ๋ฑ
- Controller: Model๊ณผ View ์ฌ์ด์ ์ํธ์์ฉ์ ์กฐ์ ํ๊ณ ์ ์ด ๊ฐ๋ฅ
- ์ฌ์ฉ์์ ์์ฒญ์ ์ ๋ ฅ๋ฐ์ Model์ ์ ๋ฌ
- ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํ์ผ๋ก View ์ ๋ฐ์ดํธ

Spring MVC
Spring ๊ณต์๋ฌธ์์์ Spring MVC๋ DispatcherServlet์ด ์ค์์์ HTTP ์์ฒญ์ ์ฒ๋ฆฌํด์ฃผ๋๋ฐ ์ด๋ Front Controller ํจํด์ผ๋ก ์ค๊ณ๋์ด ์๋ค๊ณ ์ค๋ช ํ๊ณ ์์.
์ฆ, Spring์์ MVC ๋์์ธ ํจํด์ ์ ์ฉํด HTTP ์์ฒญ์ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ณ ์์
Servlet(์๋ธ๋ฆฟ)
Servlet(์๋ธ๋ฆฟ)์ ์๋ฐ๋ฅผ ์ฌ์ฉํด ์น ํ์ด์ง๋ฅผ ๋์ ์ผ๋ก ์์ฑํ๋ ์๋ฒ ์ธก ํ๋ก๊ทธ๋จ ํน์ ๊ทธ ์ฌ์
* ํฐ์บฃ(Tomcat) ์์์ ์๋ธ๋ฆฟ(Servlet) ๋์
[์ฌ์ฉ์๊ฐ HTTP API ์์ฒญ ์ ์๋ฒ์ ์๋ธ๋ฆฟ ๋์ ๊ณผ์ ]

1. ํด๋ผ์ด์ธํธ๊ฐ HTTP๋ฅผ ํตํด Request ์์ฒญ
2. ์์ฒญ์ ๋ฐ์ ์๋ธ๋ฆฟ ์ปจํ ์ด๋๋ HttpServletRequest์ HttpServletResponse ๊ฐ์ฒด ์์ฑ
- ๋ ๊ฐ์ฒด๋ ์ฝ์๋ HTTP์ ๊ท๊ฒฉ์ ๋ง์ถ๋ฉด์ ์ฝ๊ฒ HTTP์ ๋ด๊ธด ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ๋ง๋ค์ด๋ธ ๊ฐ์ฒด
- ์ฆ, ์๋ธ๋ฆฟ์ด ๊ฐ๋ฐ์๋ฅผ ๋์ ํด์ HTTP๋ฅผ ๋ถ์ํด์ ๊ทธ ์์ ๋ค์ด์๋ ๋ฐ์ดํฐ์ ์ ๋ณด๋ค์ ๊ฐ์ฒด์ ๋ฃ์ด์ค
3. API ์์ฒญ ํ์ธ ํ, ๊ทธ ์์ฒญ์ด ์ด๋ค ์๋ธ๋ฆฟ๊ณผ ๋งค์นญ์ด ๋๋์ง ๋ถ์ํจ(web.xml)
4. ๋งค์นญ๋๋ ์๋ธ๋ฆฟ์ ์ฐพ์ผ๋ฉด, ํด๋น ์๋ธ๋ฆฟ์์ service() ํธ์ถ
5. ์๋น์ค ๋ฉ์๋ ํธ์ถ ํ HTTP ์์ฒญ์ด ์ด๋ค ๋ฉ์๋ ๋ฐฉ์์ธ์ง ํ์ธํ ํ ํด๋น ๋ฐฉ์์ ๋ง๋ ๋ฉ์๋ ํธ์ถ
6. ํธ์ถํ ๋ฉ์๋๋ค์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํด HttpServletResponse ๊ฐ์ฒด์ ์๋ต์ ๋ด์์ ํด๋ผ์ด์ธํธ์ ๋ฐํ
DispatcherServlet
Dispatcher๋ '์ ๋ฌํ๋ค'๋ผ๋ ์๋ฏธ๋ก, DispatcherServlet์ ์ ๋ฌํ๋ ์๋ธ๋ฆฟ
์ฌ๋ฌ ๊ฐ์ API์ ๋งค์นญ๋๋ Servlet์ ๊ฐ์ฒด๋ค์ ๊ฐ๋ฐ์๊ฐ ๊ตฌํํ๊ณ , ์ด๋ค ๋ฉ์๋ ๋ฐฉ์์ธ์ง ํ์ธํด์ ๋ฐฉ์์ ๋ง๋ ๋ฉ์๋ ํธ์ถํ๊ณ ์ํํด์ฃผ๋ ๋ฑ ๊ฐ๋ฐ์๊ฐ ์ฌ๋ฌ ๊ฐ์ง ์์ ๋ค์ ์์ฑํด์ฃผ์ด์ผํจ
์ด๋ฌํ ๋ถํธํจ์ ์คํ๋ง์์ ํด๊ฒฐํด์ฃผ๊ธฐ ์ํด DispatcherServlet์ ๋ง๋ค๊ณ , Front ์ปจํธ๋กค ํจํด ๋ฐฉ์์ผ๋ก ๋ชจ๋ API๋ค์ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ณ ์์

1. ๋ธ๋ผ์ฐ์ ์์ Request ์์ฒญ ๋ค์ด์ด
2. DispatcherServlet์ด ํด๋น ์์ฒญ ๋ถ์ ํ, ๋ถ์ํ ํ ๋๋ก Handler mapping์ ํตํด Controller๋ฅผ ์ฐพ์ ์์ฒญ ์ ๋ฌ
- Handler mapping์๋ API path์ Controller ๋ฉ์๋๊ฐ ๋งค์นญ๋์ด ์์
@RestController
public class HelloController {
@GetMapping("/api/hello")
public String hello() {
return "Hello World!";
}
}
3. Controller๋ ํด๋น ์์ฒญ์ ๋ํ ์์ ์ํ ํ, ์์ฒญ์ ๋ํ ๊ฒฐ๊ณผ๋ฅผ Model์ ๋ด๊ณ , View์ ๋ํ ์ ๋ณด๋ ์ ๋ฌํด์ค
4. DispatcherServlet์ ํตํด Client์๊ฒ ์๋ต ์ ๋ฌ
- ViewResolver๋ฅผ ํตํด View์ Model ์ ์ฉํด View๋ฅผ Client์๊ฒ ์๋ต์ผ๋ก ์ ๋ฌ
Controller ์ดํดํ๊ธฐ
Controller์ ์ฅ์

- Spring MVC์ Front Controller ํจํด์ด ์ ์ฉ๋์ด ์์ง ์๋ ๊ฒฝ์ฐ, ๋จ 4๊ฐ์ API๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด 3๊ฐ์ ํด๋์ค๋ฅผ ๋ง๋ค์ด์ผ ํจ
- ํ์ง๋ง Spring MVC๋ ํจ์จ์ ์ธ API ์ฒ๋ฆฌ๋ฅผ ์ํด Front Controller ํจํด์ ๋ง๋ค์๊ธฐ ๋๋ฌธ์, API๋ง๋ค ํ์ผ์ ๋ง๋ค ํ์ X
- ๋ณดํต ํ๋์ Controller์ ๋ชจ๋ API๋ฅผ ๋ฃ์ง ์๊ณ , ์ ์ฌํ ์ฑ๊ฒฉ์ API๋ฅผ ํ๋์ Controller๋ก ๊ด๋ฆฌํจ
- ๋ฉ์๋ ์ด๋ฆ๋ ๋ง์๋๋ก ์ค์ ๊ฐ๋ฅํจ!

Controller ๋ง๋ค๊ธฐ
1. ํ๋ก์ ํธ ์์ฑ ํ Controller ํ์ผ ์์ฑ



2. API ๋ง๋ค๊ธฐ
* ๊ฒฝ๋ก๋ ์ค๋ณต์ด ๋ ์ ์์ง๋ง, Method๊น์ง ์ค๋ณต X
package com.sparta.springmvc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller
public class HelloController {
@GetMapping("/api/hello")
@ResponseBody
public String hello() {
return "Hello World!";
}
@GetMapping("/api/get")
@ResponseBody
public String get(){
return "GET Method ์์ฒญ";
}
@PostMapping("/api/hello")
@ResponseBody
public String postHello() {
return "Hello Post World!";
}
@PostMapping("/api/post")
@ResponseBody
public String post() {
return "POST Method ์์ฒญ";
}
@PutMapping("/api/put")
@ResponseBody
public String put() {
return "PUT Method ์์ฒญ";
}
@DeleteMapping("/api/delete")
@ResponseBody
public String delete() {
return "DELETE Method ์์ฒญ";
}
}



3. ์ค๋ณต ์ฝ๋ ์์ ๊ธฐ
@RequestMapping์ ์๋จ์ ๋ฌ๊ณ , ํน์ url๋ก ์์ํ๋ ์์ฒญ์ ํด๋น ํด๋์ค๋ก ๋์ด์ด. ๊ทธ ์ดํ path์ Method ๋ฐฉ์์ ๋ถ์ํด ๋ฉ์๋์ ๋งค์นญํจ
package com.sparta.springmvc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping("/api")
public class HelloController {
@GetMapping("/hello")
@ResponseBody
public String hello() {
return "Hello World!";
}
@GetMapping("/get")
@ResponseBody
public String get(){
return "GET Method ์์ฒญ";
}
@PostMapping("/post")
@ResponseBody
public String post() {
return "POST Method ์์ฒญ";
}
@PutMapping("/put")
@ResponseBody
public String put() {
return "PUT Method ์์ฒญ";
}
@DeleteMapping("/delete")
@ResponseBody
public String delete() {
return "DELETE Method ์์ฒญ";
}
}
์ ์ ํ์ด์ง์ ๋์ ํ์ด์ง
thymeleaf: ํ ํ๋ฆฟ ์์ง์ผ๋ก ๋์ ์ธ ์นํ์ด์ง ์ฆ, ๋์ ์ธ HTML ํ์ผ์ ๋ง๋ค๊ธฐ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
์ ์ ํ์ด์ง ์ฒ๋ฆฌ
static ํด๋์ ์๋ HTML์ ์ ๊ทผํ๊ธฐ ์ํ ๋ฐฉ๋ฒ

1. URL ๊ฒฝ๋ก์์ ์ง์ ์ ๊ทผ

2. thymeleaf๊ฐ ์์ง์ ๊ฑธ๋ ค ์์ง ์์ ์ํฉ์์ Controller๋ฅผ ํตํด ์ ๊ทผ
package com.sparta.springmvc.html;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HtmlController {
@GetMapping("/static-hello")
public String hello() {
return "hello.html";
}
}

3. redirect๋ก ์ ๊ทผ
package com.sparta.springmvc.html;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HtmlController {
@GetMapping("/static-hello")
public String hello() {
return "hello.html";
}
@GetMapping("/html/redirect")
public String htmlStatic() {
return "redirect:/hello.html"; // ์ฌํธ์ถ
}
}


templates ํด๋์ ์๋ HTML์ ์ ๊ทผํ๊ธฐ

package com.sparta.springmvc.html;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HtmlController {
@GetMapping("/html/templates")
public String htmlTemplate(){
return "hello";
}
}

๋์ ํ์ด์ง ์ฒ๋ฆฌ
๋ฐํํ ๋ฐ์ดํฐ๋ Model์ ๋ด๊ณ , ๊ทธ Model์ด ์ ์ฉ๋ View name์ ์ ๋ณด ์ ๋ฌํ๋ฉด View Resolver๋ฅผ ํตํด์ ๊ทธ Model์ ๋ฐ์ดํฐ๊ฐ View์ ์ ์ฉ๋๊ณ ์์ฑ๋ ํ์ด์ง๋ฅผ ํด๋ผ์ด์ธํธ์ ๋ฐํํ๋ ๊ณผ์
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>Hello Spring</title></head>
<body>
<div>
Hello, Spring ๋์ ์น ํ์ด์ง!!
</div>
<div>
(๋ฐฉ๋ฌธ์ ์: <span th:text="${visits}"></span>)
</div>
</body>
</html>
package com.sparta.springmvc.html;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HtmlController {
private static long visitCount = 0; // ๋ฐฉ๋ฌธ ํ์
@GetMapping("/html/dynamic")
public String htmlDynamic(Model model) {
visitCount++;
model.addAttribute("visits", visitCount);
return "hello-visit";
}
}

๋ฐ์ดํฐ๋ฅผ Client์ ๋ฐํํ๋ ๋ฐฉ๋ฒ

์น ์ํ๊ณ์์ ์๋ฒ๋ MySQL๊ณผ ๊ฐ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์๋ฒ์์ ๋ฐ์์จ ๋ฐ์ดํฐ๋ฅผ ํด๋ผ์ด์ธํธ์ ๋ฐํํด์ฃผ๋ฉด, ํด๋ผ์ด์ธํธ๊ฐ ํด๋น ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ๋ธ๋ผ์ฐ์ ๋ฅผ ํตํด ์ฌ์ฉ์์๊ฒ ๊ฒฐ๊ณผ๊ฐ์ ๋ณด์ฌ์ฃผ๋ ํํ๋ก ๋ฐ์ ํ๊ณ ์์
์ฆ, Client ์ชฝ์ ๊ฐ๋ฐํ๋ Frontend์ ์๋ฒ ์ชฝ์ ๊ฐ๋ฐํ๋ Backend๊ฐ ์๋ก ๋์จํ๊ฒ ๊ฒฐํฉ๋๋ ๋ฐฉ์์ ๋ ๋ง์ด ์ฑํํ๊ณ ์์
์๋ฒ์์ ๋ฐ์ดํฐ ๊ตํ ํฌ๋งท ์ค์ JSON์ด๋ผ๋ ํํ๋ก ๋ฐ์ดํฐ ๋ฐํํ๊ณ ์์

- Client์์ ์ต์ด Requestํ๋ฉด ์ ์ HTML ํน์ ๋์ HTML ๋ฐํ
- ๊ทธ ์ดํ์๋ ์๋ฐ์คํฌ๋ฆฝํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ธ AJAX๋ก ๋น๋๊ธฐ์ ์ผ๋ก ์๋ฒ์ ์์ฒญ์ด ๋ค์ด์ ์๋ฒ๋ JSON ํํ๋ก ๋ฐํ
- JSON์ ์๋ฐ์คํฌ๋ฆฝํธ ์ชฝ์์ ์๋ ํ์ ์ด๊ธฐ ๋๋ฌธ์ ์๋ฐ์์ ์ฝ์ ์ X
- ์ฆ, ์๋ต์ ๋ฐํํด์ค ๋ JSON ํ์์ฒ๋ผ ์๊ธด String ํ์์ผ๋ก ์์ฑ
String ๋ฐํ
package com.sparta.springmvc.response;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/response")
public class ResponseController {
// Content-Type: text/html
// Response Body
// {"name":"Robbie", "age":95}
@GetMapping("/json/string")
@ResponseBody
public String helloStringJson() {
return "{\"name\":\"Robbie\",\"age\":95}";
}
}

์๋ฐ ํด๋์ค ๋ฐํ
์๋ฐ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ฉด Spring ๋ด๋ถ์ ์ผ๋ก ์๋ฐ ๊ฐ์ฒด๋ฅผ JSON ํํ๋ก ๋ณํํด์ค
package com.sparta.springmvc.response;
import lombok.Getter;
@Getter
public class Star {
String name;
int age;
public Star(String name, int age) {
this.name = name;
this.age = age;
}
public Star() {}
}
package com.sparta.springmvc.response;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/response")
public class ResponseController {
// Content-Type: text/html
// Response Body
// {"name":"Robbie", "age":95}
@GetMapping("/json/string")
@ResponseBody
public String helloStringJson() {
return "{\"name\":\"Robbie\",\"age\":95}";
}
// Content-Type: application/json
// Response Body
// {"name":"Robbie", "age":95}
@GetMapping("/json/class")
@ResponseBody
public Star helloClassJson(){
return new Star("Robbie", 95);
}
}

RestController
RestController๋ Controller + ResponseBody๋ก, ๋ฉ์๋์ ๋ฐ๋ก ResponseBody๋ฅผ ๋ฌ์ง ์์๋ ๋จ!
package com.sparta.springmvc.response;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/response/rest")
public class ResponseRestController {
// [Response header]
// Content-Type: text/html
// [Response body]
// {"name":"Robbie","age":95}
@GetMapping("/json/string")
public String helloStringJson() {
return "{\"name\":\"Robbie\",\"age\":95}";
}
// [Response header]
// Content-Type: application/json
// [Response body]
// {"name":"Robbie","age":95}
@GetMapping("/json/class")
public Star helloClassJson() {
return new Star("Robbie", 95);
}
}
Jackson
Jackson์ JSON ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ฒ๋ฆฌํด์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก, Object(=์๋ฐ ๊ฐ์ฒด)๋ฅผ JSON ํ์ ์ String์ผ๋ก ๋ณํํด ์ค ์ ์๊ณ , ๋ฐ๋๋ก JSON ํ์ ์ String ๊ฐ์ Object๋ก ๋ณํํด ์ค ์ ์์
- Spring 3.0 ๋ฒ์ ์ดํ๋ก Jackson๊ณผ ๊ด๋ จ๋ API ์ ๊ณต
ObjectMapper ํด๋์ค ์ฌ์ฉํด์ Object → JSON ํํ ํน์ JSON → Object ํํ ๋ณํ
Object → JSON
- ์๋ฐ ํด๋์ค ๋ด์ Getter ๋ฉ์๋ ๋ฐ๋์ ํ์ํจ! → ์ง๋ ฌํ ์ํ์ ์ํด
package com.sparta.springmvc;
import com.sparta.springmvc.response.Star;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import tools.jackson.databind.ObjectMapper;
public class JacksonTest {
@Test
@DisplayName("Object To JSON : get Method ํ์")
void test1() {
Star star = new Star("Robbie", 95);
ObjectMapper objectMapper = new ObjectMapper(); // Jackson ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ObjectMapper
String json = objectMapper.writeValueAsString(star);
System.out.println("json = " + json);
}
}
JSON → Object
- ์๋ฐ ํด๋์ค ๋ด์ ๊ธฐ๋ณธ ์์ฑ์์ Getter ํน์ Setter ํ์! → ์ญ์ง๋ ฌํ ์ํ์ ์ํด
package com.sparta.springmvc;
import com.sparta.springmvc.response.Star;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import tools.jackson.databind.ObjectMapper;
public class JacksonTest {
@Test
@DisplayName("JSON To Object : ๊ธฐ๋ณธ ์์ฑ์ & (get OR set) Method ํ์")
void test2() {
String json = "{\"name\":\"Robbie\",\"age\":95}"; // JSON ํ์
์ String
ObjectMapper objectMapper = new ObjectMapper(); // Jackson ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ObjectMapper
Star star = objectMapper.readValue(json, Star.class);
System.out.println("star.getName() = " + star.getName());
}
}
Path Variable๊ณผ Request Param
ํด๋ผ์ด์ธํธ์์ ์์ฒญ์ ๋ณด๋ผ ๋ ๋ฐ์ดํฐ๋ฅผ ํจ๊ป ๋ณด๋ผ ์ ์์. ์๋ฒ์์๋ ์ด ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ ์ฌ์ฉํด์ผํจ. ํ์ง๋ง ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๋ ๋ฐฉ์์ด ์ฌ๋ฌ ๊ฐ์ง๊ฐ ์๊ธฐ ๋๋ฌธ์ ๋ชจ๋ ๋ฐฉ์์ ๋ํ ์ฒ๋ฆฌ ๋ฐฉ๋ฒ ํ์ตํด์ผ ํจ

Path Variable
๋ณด๋ด๋ ค๊ณ ํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ธ๋ผ์ฐ์ ์์ ๊ฒฝ๋ก์ ๋ฃ๋ ๊ฒ
- URL ๊ฒฝ๋ก์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊ณ ์ ํ๋ ์์น์ ๊ฒฝ๋ก์ {data} ์ค๊ดํธ ์ฌ์ฉ
- ํด๋น ์์ฒญ ๋ฉ์๋ ํ๋ผ๋ฏธํฐ์ @PathVariable ์ ๋ํ ์ด์ ๊ณผ ํจ๊ป {data} ์ค๊ดํธ์ ์ ์ธํ ๋ณ์๋ช ๊ณผ ๋ณ์ํ์ ์ ์ ์ธํด์ ํด๋น ๊ฒฝ๋ก์ ๋ฐ์ดํฐ ๋ฐ์์ด
package com.sparta.springmvc.request;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/hello/request")
public class RequestController {
// [Request sample]
// GET http://localhost:8080/hello/request/star/Robbie/age/95
@GetMapping("/star/{name}/age/{age}")
@ResponseBody
public String helloRequestPath(@PathVariable String name, @PathVariable int age)
{
return String.format("Hello, @PathVariable.<br> name = %s, age = %d", name, age);
}
}

Request Param(ํน์ Query String)
URL ๋ด ๊ฒฝ๋ก ๋ค์ Query String ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์์ํ ๋ ๋ฌผ์ํ๋ก ์์ํ๊ณ , Key-Value ํํ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ฃ์. ๋ฐ์ดํฐ ์ฌ๋ฌ ๊ฐ๋ฅผ ๋ณด๋ผ ๋์๋ &๋ก ์ฐ๊ฒฐ
- ํด๋น ์์ฒญ ๋ฉ์๋ ํ๋ผ๋ฏธํฐ์ @RequestParam ์ ๋ํ ์ด์ ๊ณผ ํจ๊ป key ๋ถ๋ถ์ ์ ์ธํ ๋ณ์๋ช ๊ณผ ๋ณ์ํ์ ์ ์ ์ธํด ๋ฐ์ดํฐ ๋ฐ์์ด
package com.sparta.springmvc.request;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping("/hello/request")
public class RequestController {
// [Request sample]
// GET http://localhost:8080/hello/request/form/param?name=Robbie&age=95
@GetMapping("/form/param")
@ResponseBody
public String helloGetRequestParam(@RequestParam String name, @RequestParam int age) {
return String.format("Hello, @RequestParam.<br> name = %s, age = %d", name, age);
}
}

- ํ๋ผ๋ฏธํฐ์ @RequestParam ์ ๋ํ ์ด์ ์๋ต ๊ฐ๋ฅ
// [Request sample]
// GET http://localhost:8080/hello/request/form/param?name=Robbie&age=95
@GetMapping("/form/param")
@ResponseBody
public String helloGetRequestParam(@RequestParam String name, int age) {
return String.format("Hello, @RequestParam.<br> name = %s, age = %d", name, age);
}
- ํด๋ผ์ด์ธํธ์์ ์ ๋ฌ๋ฐ์ ๊ฐ๋ค ์ค ํด๋น ๊ฐ์ด ํฌํจ๋์ง ์์๋ ๋๋ ๊ฒฝ์ฐ์ ์ต์
์ค์ → default๋ก true๊ฐ ์ค์ ๋์ด ์์!(@PathVariable๋ ๋์ผ)
- ์๋ค์ด์ค๋ ๊ฒฝ์ฐ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง๋ ์์ง๋ง, null ๊ฐ์ด ๋ค์ด์ด
// [Request sample]
// GET http://localhost:8080/hello/request/form/param?name=Robbie&age=95
@GetMapping("/form/param")
@ResponseBody
public String helloGetRequestParam(@RequestParam(required = false) String name, @RequestParam int age) {
return String.format("Hello, @RequestParam.<br> name = %s, age = %d", name, age);
}
form ํ๊ทธ POST
HTML ๋ด์ form ํ๊ทธ ์ฌ์ฉํ๋ฉด URL ์์ฒญ ๊ฐ๋ฅ
- POST๋ GET๊ณผ ๋ฌ๋ฆฌ body๋ฅผ ๊ฐ์ง๊ณ ์์. Payload ๋ถ๋ถ์ ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ผ ์ ์์
<h2>POST /hello/request/form/param</h2>
<form method="POST" action="/hello/request/form/param">
<div>
์ด๋ฆ: <input name="name" type="text">
</div>
<div>
๋์ด: <input name="age" type="text">
</div>
<button>์ ์ก</button>
</form>
<br>
package com.sparta.springmvc.request;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping("/hello/request")
public class RequestController {
// [Request sample]
// POST http://localhost:8080/hello/request/form/param
// Header
// Content type: application/x-www-form-urlencoded
// Body
// name=Robbie&age=95
@PostMapping("/form/param")
@ResponseBody
public String helloPostRequestParam(@RequestParam String name, @RequestParam int age) {
return String.format("Hello, @RequestParam.<br> name = %s, age = %d", name, age);
}
}


HTTP ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฒด๋ก ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ
@ModelAttribute ์ ๋ ธํ ์ด์
Body์ Query String ๋ฐฉ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฒด์ Mapping
body ๋ถ๋ถ์ ๋ค์ด์จ Query String ๋ฐฉ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฒด์ mappingํด์ ๊ฐ์ง๊ณ ์ฌ ์ ์์
- ํด๋์ค(๊ฐ์ฒด)์ ํ๋ ์ด๋ฆ๊ณผ ํด๋ผ์ด์ธํธ์์ ๋ณด๋ด๋ ๋ฐ์ดํฐ ์ด๋ฆ์ด ๋์ผํด์ผํจ
// [Request sample]
// POST http://localhost:8080/hello/request/form/model
// Header
// Content type: application/x-www-form-urlencoded
// Body
// name=Robbie&age=95
@PostMapping("/form/model")
@ResponseBody
public String helloRequestBodyForm(@ModelAttribute Star star) {
return String.format("Hello, @ModelAttribute.<br> (name = %s, age = %d) ", star.name, star.age);
}

Request Param ๋ฐฉ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฒด์ Mapping
request param ๋ฐฉ์๋ @ModelAttribute๋ฅผ ์ด์ฉํด์ ๊ฐ์ฒด๋ก ๋ฐ์์ฌ ์ ์์
- @ModelAttribute๋ Setter ํน์ ์ค๋ฒ๋ก๋ฉ๋ ์์ฑ์ ๋ฐ๋์ ํ์ํจ!
// [Request sample]
// GET http://localhost:8080/hello/request/form/param/model?name=Robbie&age=95
@GetMapping("/form/param/model")
@ResponseBody
public String helloRequestParam(@ModelAttribute Star star) {
return String.format("Hello, @ModelAttribute.<br> (name = %s, age = %d) ", star.name, star.age);
}

@ModelAttribute ์๋ตํ๊ธฐ
// [Request sample]
// GET http://localhost:8080/hello/request/form/param/model?name=Robbie&age=95
@GetMapping("/form/param/model")
@ResponseBody
public String helloRequestParam(Star star) {
return String.format("Hello, @ModelAttribute.<br> (name = %s, age = %d) ", star.name, star.age);
}
โ Spring์์ @RequestParam๊ณผ @ModelAttribute ๋ชจ๋ ์๋ต์ด ๊ฐ๋ฅํ๋ฐ ์ด๋ป๊ฒ ๊ตฌ๋ถํ ๊น?
๐ฃ๏ธ Spring์ ํด๋น ํ๋ผ๋ฏธํฐ๊ฐ SimpleValueType(์์ํ์ , Wrapper, Date ํ์ )์ด๋ฉด @RequestParam์ผ๋ก ๊ฐ์ฃผํ๊ณ ,
์๋๋ผ๋ฉด @ModelAttribute๊ฐ ์๋ต์ด ๋์๋ค๊ณ ํ๋จํจ
Body์ JSON ํ์์ผ๋ก ๋์ด์จ ๊ฒฝ์ฐ
HTTP Body ๋ถ๋ถ์ JSON ํ์์ผ๋ก ๋ฐ์ดํฐ๊ฐ ๋์ด์์ ๋์ @RequestBody ์ ๋ ธํ ์ด์ ์ ๊ผญ ๋ถ์ฌ์ฃผ์ด์ผ ํจ!
- field๋ฅผ ๊ผญ ๋ง์ถฐ์ฃผ์ด์ผ ํจ!
// [Request sample]
// POST http://localhost:8080/hello/request/form/json
// Header
// Content type: application/json
// Body
// {"name":"Robbie","age":"95"}
@PostMapping("/form/json")
@ResponseBody
public String helloPostRequestJson(@RequestBody Star star) {
return String.format("Hello, @RequestBody.<br> (name = %s, age = %d) ", star.name, star.age);
}
