Spring [@RequestMapping ๊ธฐ์ด ์ ๋ฆฌ ]
์คํ๋ง ์ ๋ฌธ ๊ฐ์, ๊ธฐ์ด๊ฐ์๋ฅผ ๋ค์์ ๋ ์ข ์ข ๋ณด์๋ RequestMapping์ ๋ํ ๊ธฐ์ด๋ฅผ ๋ค์ ๋ค์ก๋ค!
์์ง ๊ธฐ์ด๋ง ๋ฐฐ์ด ๊ฑฐ๋ผ ์ค๋ฌด์์ ์ด๋์ ์ฌ์ฉํ ์ง ๊ฐ๋ฐ์ ์ค์ง ์์ง๋ง ์ธ์ ๊ฐ ๋ฅ์๋ฅ๋ํ๊ฒ ๋ค๋ฃจ๊ณ ์ถ๋ค๐
RequestMapping(์์ฒญ ๋งคํ) ์ด๋?
์์ฒญ์ด ์์ ๋ ์ด๋ค ์ปจํธ๋กค๋ฌ๊ฐ ํธ์ถ์ด ๋์ด์ผ ํ๋์ง ์๋ ค์ฃผ๋ ์งํ ๊ฐ์ ๊ฒ์ด๋ค.
๐ ์์
@RequestMapping(value = "/hello-basic")
์ด๋ ๊ฒ ๋งคํ์ ํ๋ฉด localhost:8080/hello-basic์ผ๋ก url์ ์ ๋ ฅํ์ ๊ฒฝ์ฐ์ ์ด๊ฒ์ ํด๋นํ๋ ๋ฉ์๋๊ฐ ์คํ๋๋ค.
@RequestMapping์ ๋ค์ค์์ฒญ๋ ๊ฐ๋ฅํ๋ค!
๋ค์ค ์์ฒญ์ ํ๋ ค๋ฉด ๋ฐฐ์ด๋ก ๋ฌถ์ด์ผ ํ๋ค.
@RequestMapping(value = {"/hello", "/hello-basic"})
์ด๊ฒ์ฒ๋ผ ๋ค์ค ์์ฒญ์ ํ ๊ฒฝ์ฐ์๋ ๋ ์ค ์๋ฌด url์ด๋ ์ ๋ ฅํด๋ ๋๋ค.
[ ๊ฒฝ๋ก๋ณ์(PathVariable) ์ฌ์ฉ ]
์ต๊ทผ HTTP API๋ ๋ฆฌ์์ค ๊ฒฝ๋ก์ ์๋ณ์๋ฅผ ๋ฃ๋ ์คํ์ผ์ ์ ํธํ๋ค.
์ฟผ๋ฆฌ ํ๋ง๋ฆฌํฐ๋ก ์๋ณ์๋ฅผ ๋ฃ๋ ๋ฐฉ๋ฒ๋ ์์ง๋ง ๊ฒฝ๋ก ๋ณ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋งคํ๋๋ ๋ถ๋ถ์ ํธ๋ฆฌํ๊ฒ ์กฐํํ ์ ์๋ค.
๐ ์์
@GetMapping("/mapping/{userId}")
public String mappingPath(@PathVariable("userId") String data) {
log.info("mappingPath userId={}", data);
return "ok";
}
localhost:8080/mapping/userA
๋ผ๊ณ ์ ๋ ฅํ๋ฉด userId๊ฐ data๋ก ๋งค์นญ๋ผ์ ํธํ๊ฒ ์ฌ์ฉํ ์ ์๋ค.
์ ๋ ๊ฒ data๋ก ๊บผ๋ด๋ ๋ฐฉ์์ผ๋ก ๋ง๊ณ ํ๋ผ๋ฏธํฐ ์ด๋ฆ์ด ๊ฐ์ผ๋ฉด ์๋ต ๊ฐ๋ฅํ๋ค.
@GetMapping("mapping/{userId}")
public String mappingPath(@PathVariable String userId) {
log.info("mappingPath userId={}", userId);
return "ok";
}
โ PathVariable ๋ค์ค ์ฌ์ฉ
@GetMapping("/mapping/users/{userId}/orders/{orderId}")
public String mappingPath(@PathVariable String userId, @PathVariable Long orderId) {
log.info("mappingPath userId={}, orderId={}", userId, orderId);
return "ok";
}
์ด๋ ๊ฒ ๋ค์ค์ผ๋ก ์ฌ์ฉํ ์๋ ์๋ค!!!
[ ํน์ ํค๋ ์กฐ๊ฑด ๋งคํ ]
@GetMapping(value = "/mapping-header", headers = "mode=debug")
public String mappingHeader() {
log.info("mappingHeader");
return "ok";
}
์ด๋ ๊ฒ ์์ฑํ์ ๊ฒฝ์ฐ์๋ localhost:8080/mapping-header์ผ๋ก ์ด๋ํ์ ๋ ์ค๋ฅ ํ์ด์ง๊ฐ ๋ฌ๋ค!
์ด๋ฐ ๊ฒฝ์ฐ์๋ localhost:8080/mapping-header?mode=debug๋ก ์ด๋ํด์ผ ์ ์์ ์ธ ํ์ด์ง๋ก ์ ๊ทผ์ด ๊ฐ๋ฅํ๋ค.
[ ๋ฏธ๋์ด ํ์ ๋งคํ ]
HTTP ์์ฒญ์ Content-Type ํค๋๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ฏธ๋์ด ํ์ ์ผ๋ก ๋งคํํ๋ค.
๋ง์ฝ ๋ง์ง ์์ผ๋ฉด HTTP ์ํ ์ฝ๋๋ฅผ ๋ฐํํ๋ค.
๐ ์ฌ๊ธฐ์ Content-Type์ ๊ดํ ๋ด์ฉ์ด ๊ฐ๋ตํ๊ฒ ์์ฝ๋์ด์๋ค!
comsumes๋ ์๋นํ๋ ์ ์ฅ์ด๋ค. ์์ฐ์ produce!
ํฌ์คํธ๋งจ์ผ๋ก ์ค์ต์ ํด๋ณด์๊ธฐ ๋๋ฌธ์ Accept๋ฅผ ๋ณ๊ฒฝํ๋ฉด์ ์ค์ตํด๋ณด์๋ค.
Accept์๋ ์ด๋ค ๋ฏธ๋์ด ํ์ ์ ๋ฐ์๋ค์ผ ์ ์๋์ง ์ ๋ ฅํ๋ฉด ๋๋ค.
๐ consume ์์
@PostMapping(value = "/mapping-consume", consumes = MediaType.APPLICATION_JSON_VALUE)
// = (consumes = "application/json")
public String mappingConsumes() {
log.info("mappingConsumes");
return "ok";
}
์ด๋ฐ ๊ฒฝ์ฐ์๋ Content-Type์ด application/josn์ผ ๋๋ง ์ฌ์ฉํ ์ ์๋ค.
๐ป POSTMAN์ผ๋ก ์ค์ตํด๋ณด์!
โพ Content-Type์ text๋ก ํด๋ดค์ ๋
์ด๋ ๊ฒ HTTP 415 ์ํ์ฝ๋๋ฅผ ๋ฐํํ๋ค!
โพ ์๋ง์ json ํํ๋ก ์ค์ ํ์ ๋
์๋ง๊ฒ ๋ฐํ๋์์ ์ ์ ์๋ค.
๐ produce ์์
@PostMapping(value = "/mapping-produce", produces = MediaType.TEXT_HTML_VALUE)
// = (produces = "text/html")
public String mappingProduces() {
log.info("mappingProduces");
return "ok";
}
์์ฒ๋ผ produces๋ text/html๋ก ์ค์ ํ๊ฒ ๋๋ฉด, html๋ง์ ์ถ๋ ฅํ ์ ์๋ค.
์ด๊ฒ๋ ํฌ์คํธ๋งจ์ผ๋ก ํ์ธํด๋ณด์!
ํฌ์คํธ๋งจ์ header์ ์๋ Accept๋ก ๋ฏธ๋์ด ํ์ ์ ๋ณ๊ฒฝํ ์ ์๋ค.
โพ Accept๋ฅผ json (or ๋ค๋ฅธ ํ์ )์ผ๋ก ์ค์ ํ์ ๋
์ด๋ ๊ฒ HTTP 406 ์ํ ์ฝ๋๋ฅผ ๋ฐํํ๋ค!! application/json์ผ๋ก ํ๋ฉด jsonํํ๋ง ์ถ๋ ฅํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
โพ text/html๋ก ์ ๋ ฅํ์ ๋ ( */*๋ก ํด๋ ์ ์๋๋จ)
์ ์ถ๋ ฅ๋๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
์ด ๊ฐ๋ ์ ๋ฐฐ์ฐ๊ณ ํ์๊ด๋ฆฌ api์ ์ ์ฉ๋ง ํด๋ณด์๋๋ฐ, ํ์คํ ์ฝ๋๋ ์งง์์ง๊ณ ๊ฐ์ url์ ์ฌ์ฉํ๋๋ผ๋ ๋ฉ์๋ ๋ฐฉ์์ ๋ณํ์์ผ์ ์ข ๋ ํจ์จ์ ์ผ๋ก ์ฌ์ฉํ ์ ์๋ ๊ฒ ๊ฐ๋ค.
์ด ํฌ์คํ ์ ์ธํ๋ฐ ๊น์ํ๋์ [์คํ๋งMVC 1ํธ - ๋ฐฑ์๋ ์น ๊ฐ๋ฐ ํต์ฌ ๊ธฐ์ ]์ ๋ฃ๊ณ ์์ฑ๋ ๋ณต์ต ์ ๋ฆฌ ํฌ์คํ ์ ๋๋ค.