Search
Duplicate

Spring MVC - ์š”์ฒญ & ์‘๋‹ต

Spring MVC - ์š”์ฒญ & ์‘๋‹ต

์š”์ฒญ ๊ฒฝ๋กœ ๋งคํ•‘

โ€ข
๋ ˆ๋ฒจ ๋งคํ•‘
โ—ฆ
ํด๋ž˜์Šค ๋ ˆ๋ฒจ ๋งคํ•‘
โ—ฆ
๋ฉ”์†Œ๋“œ ๋ ˆ๋ฒจ ๋งคํ•‘
โ€ข
๊ฒฝ๋กœ ํŒจํ„ด ๋งคํ•‘
โ€ข
์š”์ฒญ ๋ฉ”์†Œ๋“œ ๋งคํ•‘
โ€ข
ํŒŒ๋ผ๋ฏธํ„ฐ ๋งคํ•‘
โ€ข
ํ—ค๋” ๋งคํ•‘
โ€ข
ContentType ๋งคํ•‘
โ€ข
Accept ๋งคํ•‘

๋ชจ๋ธ

โ€ข
Model ์ธํ„ฐํŽ˜์ด์Šค
โ€ข
๋ชจ๋ธ ๋“ฑ๋ก
โ€ข
@ModelAttribute
โ€ข
@RequestParam
โ€ข
RedirectAttributes

์‘๋‹ต ์ฒ˜๋ฆฌ

โ€ข
void
โ€ข
String
โ€ข
ModelAndView
โ€ข
ํด๋ž˜์Šค
โ€ข
์ปฌ๋ ‰์…˜
โ€ข
ResponseEntity

์š”์ฒญ ์ฒ˜๋ฆฌ

โ€ข
์ฃผ์š” ์ปจํŠธ๋กค๋Ÿฌ ๋ฉ”์†Œ๋“œ ๋งค๊ฐœ๋ณ€์ˆ˜
โ€ข
์ฃผ์š” ์š”์ฒญ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์–ด๋…ธํ…Œ์ด์…˜
โ€ข
ํผ ์š”์ฒญ ์ฒ˜๋ฆฌ
โ€ข
ํŒŒ์ผ ์—…๋กœ๋“œ
โ€ข
AJAX ํŒŒ์ผ ์—…๋กœ๋“œ

์š”์ฒญ ๊ฒฝ๋กœ ๋งคํ•‘

@RequestMapping : ์š”์ฒญ ๊ฒฝ๋กœ ๋งคํ•‘ ์–ด๋…ธํ…Œ์ด์…˜

โ€ข
ํ•„์ˆ˜ ์ •๋ณด : ์š”์ฒญ ๊ฒฝ๋กœ(URL)
โ€ข
์ฃผ์š” ์†์„ฑ
โ—ฆ
value : ์š”์ฒญ ๊ฒฝ๋กœ
โ—ฆ
method : ์š”์ฒญ ๋ฉ”์†Œ๋“œ
โ–ช
RequestMethod.GET
โ–ช
RequestMethod.POST

@RequestMapping ์†์„ฑ

์†์„ฑ
์„ค๋ช…
value ๋˜๋Š” path
์š”์ฒญ์„ ๋งคํ•‘ํ•  URL ํŒจํ„ด์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
method
HTTP ์š”์ฒญ ๋ฉ”์„œ๋“œ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋“  HTTP ๋ฉ”์„œ๋“œ๋ฅผ ํ—ˆ์šฉํ•˜๋ฉฐ ๋ฐฐ์—ด๋กœ ์—ฌ๋Ÿฌ ๋ฉ”์„œ๋“œ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ: RequestMethod.GET, RequestMethod.POST ๋“ฑ.
params
์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ์กฐ๊ฑด์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ํŠน์ • ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ์กด์žฌ ์—ฌ๋ถ€๋‚˜ ๊ฐ’์— ๋”ฐ๋ผ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ: params = "paramName=paramValue"
headers
HTTP ํ—ค๋”์˜ ์กฐ๊ฑด์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ํŠน์ • ํ—ค๋”์˜ ์กด์žฌ ์—ฌ๋ถ€๋‚˜ ๊ฐ’์— ๋”ฐ๋ผ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ: headers = "Content-Type=application/json"
consumes
์š”์ฒญ์˜ ์ปจํ…์ธ  ์œ ํ˜•์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ณด๋‚ด๋Š” ๋ฐ์ดํ„ฐ์˜ ์ปจํ…์ธ  ์œ ํ˜•์— ๋”ฐ๋ผ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ: consumes = "application/json"
produces
์‘๋‹ต์˜ ์ปจํ…์ธ  ์œ ํ˜•์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„์—์„œ ์ƒ์„ฑํ•˜๋Š” ์‘๋‹ต์˜ ์ปจํ…์ธ  ์œ ํ˜•์„ ์ œํ•œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ: produces = "application/json"
name
ํ•ธ๋“ค๋Ÿฌ ๋ฉ”์„œ๋“œ์˜ ์ด๋ฆ„์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฆ„์€ ๋ฉ”์„œ๋“œ์™€ ์—ฐ๊ฒฐ๋˜๋ฉฐ XML ์„ค์ •์—์„œ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ ˆ๋ฒจ ๋งคํ•‘

ํด๋ž˜์Šค ๋ ˆ๋ฒจ ๋งคํ•‘

import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("/board") public class BoardController { // ์ด ๋ฉ”์„œ๋“œ๋Š” "/board"์™€ ์—ฐ๊ฒฐ๋œ ๊ฒฝ๋กœ์˜ ํ•˜์œ„ ๊ฒฝ๋กœ์— ๋”ฐ๋ผ ๋งคํ•‘๋ฉ๋‹ˆ๋‹ค. @RequestMapping("/list") public String list() { // ๊ฒŒ์‹œํŒ ๋ชฉ๋ก์„ ๋ณด์—ฌ์ฃผ๋Š” ๋กœ์ง์„ ์ˆ˜ํ–‰ return "board/list"; } }
Java
๋ณต์‚ฌ

๋ฉ”์†Œ๋“œ ๋ ˆ๋ฒจ ๋งคํ•‘

import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class BoardController { @RequestMapping("/board/list") public String list() { // ๊ฒŒ์‹œํŒ ๋ชฉ๋ก์„ ๋ณด์—ฌ์ฃผ๋Š” ๋กœ์ง์„ ์ˆ˜ํ–‰ return "board/list"; } }
Java
๋ณต์‚ฌ

๊ฒฝ๋กœ ํŒจํ„ด ๋งคํ•‘

: ์š”์ฒญ ๊ฒฝ๋กœ์— ๋ณ€์ˆ˜๋ฅผ ์ง€์ •ํ•˜์—ฌ ๋งคํ•‘ํ•˜๋Š” ๋ฐฉ๋ฒ•

๋ฐฉ๋ฒ•

@RequestMapping("/๊ฒฝ๋กœ/{๋ณ€์ˆ˜}") public String test(@PathVariable("๋ณ€์ˆ˜๋ช…") String ํŒŒ๋ผ๋ฏธํ„ฐ๋ช…) { return "/site/test"; }
Java
๋ณต์‚ฌ
โ€ข
BoardController.java
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller @RequestMapping("/board") public class BoardController { // "/board/read/{id}" ๊ฒฝ๋กœ์™€ ์—ฐ๊ฒฐ @RequestMapping("/read/{id}") public String read(@PathVariable("id") int id) { // id ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒŒ์‹œ๋ฌผ์„ ์กฐํšŒํ•˜๋Š” ๋กœ์ง์„ ์ˆ˜ํ–‰ // ์˜ˆ๋ฅผ ๋“ค์–ด, id์— ํ•ด๋‹นํ•˜๋Š” ๊ฒŒ์‹œ๋ฌผ์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๊ฐ€์ ธ์™€์„œ ํ™”๋ฉด์— ํ‘œ์‹œ return "/board/read"; } }
Java
๋ณต์‚ฌ

์š”์ฒญ ๋ฉ”์†Œ๋“œ ๋งคํ•‘

: ์š”์ฒญ ๋ฉ”์†Œ๋“œ๋ฅผ ๋งคํ•‘ ์กฐ๊ฑด์œผ๋กœ ๋งคํ•‘ํ•˜๋Š” ๋ฐฉ๋ฒ•

๋ฐฉ๋ฒ•

/* RequestMethod ์—ด๊ฑฐํƒ€์ž… - RequestMethod.GET - RequestMethod.POST - RequestMethod.PUT - RequestMethod.DELETE */ @RequestMapping(value = "/๊ฒฝ๋กœ", method = RequestMethod.๋ฉ”์†Œ๋“œ๋ฐฉ์‹) public String insert(Board board) { return "/board/insert"; }
Java
๋ณต์‚ฌ
โ€ข
BoardController.java
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller @RequestMapping("/board") public class BoardController { @RequestMapping(value = "/insert", method = RequestMethod.GET) public String insert() { return "/board/insert"; } @RequestMapping(value = "/insert", method = RequestMethod.POST) public String insertPro(Board board, Model model) { return "redirect:/board/list"; } }
Java
๋ณต์‚ฌ

ํŒŒ๋ผ๋ฏธํ„ฐ ๋งคํ•‘

: ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋งคํ•‘ ์กฐ๊ฑด์œผ๋กœ ๋งคํ•‘ํ•˜๋Š” ๋ฐฉ๋ฒ•

๋ฐฉ๋ฒ•

@RequestMapping(value = "/๊ฒฝ๋กœ", method = RequestMethod.๋ฉ”์†Œ๋“œ๋ฐฉ์‹, params="ํŒŒ๋ผ๋ฏธํ„ฐ๋ช…") public String read() { return "/board/read"; }
Java
๋ณต์‚ฌ
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller @RequestMapping("/board") public class BoardController { @RequestMapping(value = "/read", method = RequestMethod.GET, params="boardNo") public String read(Model model, @RequestParam("boardNo") int boardNo) { return "board/read"; } }
Java
๋ณต์‚ฌ

ํ—ค๋” ๋งคํ•‘

: ์š”์ฒญ ๋ฉ”์‹œ์ง€์˜ ํ—ค๋”๋ฅผ ๋งคํ•‘ ์กฐ๊ฑด์œผ๋กœ ์š”์ฒญ ๊ฒฝ๋กœ๋ฅผ ๋งคํ•‘ํ•˜๋Š” ๋ฐฉ๋ฒ•

๋ฐฉ๋ฒ•

@RequestMapping(value = "/๊ฒฝ๋กœ", headers="ํ—ค๋”๋ช…=ํ—ค๋”๊ฐ’") public String updatePro() { return "redirect:/board/list"; }
Java
๋ณต์‚ฌ

X-HTTP-Method-Override ํ—ค๋”

: HTTP ์š”์ฒญ ๋ฉ”์†Œ๋“œ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
X-HTTP-Method-Override=PUT X-HTTP-Method-Override=DELETE
Java
๋ณต์‚ฌ
ํด๋ผ์ด์–ธํŠธ์—์„œ ํ—ค๋”์— PUT, DELETE ํ—ค๋” ๊ฐ’์„ ์ง€์ •ํ•˜๊ณ  ์š”์ฒญ์„ ๋ณด๋‚ด๋ฉด, ์„œ๋ฒ„์ธก์—์„œ POST ๋งคํ•‘์—์„œ ํ—ค๋” ๋งคํ•‘ ์กฐ๊ฑด์„ ์ฃผ์–ด์„œ PUT, DELETE ๋ฐฉ์‹์œผ๋กœ ์˜จ ์š”์ฒญ๋„ POST ๋งคํ•‘์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

Spring Framework ์—์„œ X-HTTP-Method-Override ์‚ฌ์šฉ

HiddenHttpMethodFilter ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด <form> ํƒœ๊ทธ์˜ POST ์š”์ฒญ์—์„œ _method ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ PUT, DELETE ๋ฅผ ์ง€์ •ํ•˜์—ฌ ์šฐํšŒ์ ์œผ๋กœ PUT, DELETE ์š”์ฒญ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.
โ€ข
web.xml
<filter> <filter-name>httpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>httpMethodFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
XML
๋ณต์‚ฌ
ํด๋ผ์ด์–ธํŠธ์—์„œ ํผ ์š”์ฒญ ์ฝ”๋“œ
<h3>PUT ์š”์ฒญ</h3> <form action="<%= request.getContextPath() %>/request/board" method="post"> <!-- form ํƒœ๊ทธ์—์„œ๋Š” PUT ๋ฐฉ์‹ ์š”์ฒญ์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค. --> <!-- Spring ์˜ HiddenMethodFilter ๋ฅผ ๋“ฑ๋กํ•˜๋ฉด, ์šฐํšŒ์ ์œผ๋กœ PUT ์š”์ฒญ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค. --> <!-- _method ๋ฅผ X-HTTP-Method-Override ํ—ค๋”๋กœ ์ง€์ •ํ•œ๋‹ค. --> <!-- X-HTTP-Method-Override ํ—ค๋” - ๊ฐ’ : PUT --> <input type="hidden" name="_method" value="PUT" /> <input type="text" name="no" placeholder="๋ฒˆํ˜ธ ์ž…๋ ฅ" /> <input type="submit" value="์ˆ˜์ •" /> </form>
Java
๋ณต์‚ฌ
ํด๋ผ์ด์–ธํŠธ์—์„œ PUT ์œผ๋กœ ๋ช…์‹œํ•œ ์š”์ฒญ์„ POST ๋กœ ์ฒ˜๋ฆฌ
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestHeader; @Controller @RequestMapping("/board") public class BoardController { @RequestMapping(value = "/update", method = RequestMethod.POST, headers = "X-HTTP-Method-Override=PUT") public String updatePro() { return "redirect:/board/list"; // board/list.jsp ๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ } }
Java
๋ณต์‚ฌ

ContentType ๋งคํ•‘

๋ฐฉ๋ฒ•

@RequestMapping(value = "/๊ฒฝ๋กœ", consumes="์ปจํ…์ธ ํƒ€์ž…") public String insertPro() { return "redirect:/board/list"; }
Java
๋ณต์‚ฌ

Accept ๋งคํ•‘

: Aceept ํ—ค๋” ๋ฅผ ๋งคํ•‘ ์กฐ๊ฑด์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ์š”์ฒญ ๊ฒฝ๋กœ ๋งคํ•‘ ๋ฐฉ๋ฒ•

Aceept ํ—ค๋”

: ์‘๋‹ต ์ปจํ…์ธ  ํƒ€์ž…์„ ์ง€์ •ํ•˜๋Š” ํ—ค๋” ์ •๋ณด
ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„์— ์›ํ•˜๋Š” ์ปจํ…์ธ  ํƒ€์ž…์„ ์•Œ๋ ค์ฃผ๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉ
์š”์ฒญ ๋ฉ”์‹œ์ง€์˜ Accept ํ—ค๋” ๊ฐ’์„ ๋งคํ•‘ ์กฐ๊ฑด์œผ๋กœ ์ง€์ •ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” produces ์†์„ฑ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋ฐฉ๋ฒ•

@RequestMapping(value = "/๊ฒฝ๋กœ", produces="์‘๋‹ต์ปจํ…์ธ ํƒ€์ž…") public ResponseEntity<List<Board>> listJSON() { List<Board> boardList = boardService.list(); return new ResponseEntity<List<Board>>(boardList, HttpStatus.OK);; }
Java
๋ณต์‚ฌ

JSON ํ˜•์‹์„ ์‘๋‹ตํ•˜๊ธฐ ์œ„ํ•œ ์˜์กด์„ฑ

jackson-databind

Jackson ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ค‘์š”ํ•œ ๋ชจ๋“ˆ ์ค‘ ํ•˜๋‚˜๋กœ, Java ๊ฐ์ฒด์™€ JSON ๋ฐ์ดํ„ฐ ๊ฐ„์˜ ๋ณ€ํ™˜์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” Java ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค.
โ€ข
pom.xml
<!-- JSON ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์„ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.15.2</version> </dependency>
XML
๋ณต์‚ฌ

XML ํ˜•์‹์„ ์‘๋‹ตํ•˜๊ธฐ ์œ„ํ•œ ์˜์กด์„ฑ

jackson-dataformat-xml

Jackson ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ํ•œ ๋ถ€๋ถ„์œผ๋กœ์„œ, Java ๊ฐ์ฒด์™€ XML ๋ฐ์ดํ„ฐ ๊ฐ„์˜ ์ƒํ˜ธ ๋ณ€ํ™˜์„ ์ง€์›ํ•˜๋Š” Java ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค.
โ€ข
pom.xml
<!-- XML ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์„ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ --> <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> <version>2.15.2</version> </dependency>
XML
๋ณต์‚ฌ

JSON ์œผ๋กœ Accept ๋งคํ•‘ (produces)

@RequestMapping(value = "/board/list", produces="application/json") public ResponseEntity<List<Board>> listJSON() { List<Board> boardList = boardService.list(); return new ResponseEntity<List<Board>>(boardList, HttpStatus.OK); }
Java
๋ณต์‚ฌ

XML ๋กœ Accept ๋งคํ•‘ (produces)

@RequestMapping(value = "/board/list", produces="application/xml") public ResponseEntity<List<Board>> listXML() { List<Board> boardList = boardService.list(); return new ResponseEntity<List<Board>>(boardList, HttpStatus.OK); }
Java
๋ณต์‚ฌ

๋ชจ๋ธ

โ€ข
Model ์ธํ„ฐํŽ˜์ด์Šค
โ€ข
๋ชจ๋ธ ๋“ฑ๋ก
โ€ข
@ModelAttribute
โ€ข
@RequestParam
โ€ข
RedirectAttributes

Model

์ปจํŠธ๋กค๋Ÿฌ์—์„œ ๋“ฑ๋กํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ทฐ์— ์ „๋‹ฌํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค

๋ชจ๋ธ ๋“ฑ๋ก

โ€ข
Model ์ธํ„ฐํŽ˜์ด์Šค์˜ addAttribute() ๋ฉ”์†Œ๋“œ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋“ฑ๋กํ•˜์—ฌ, ๋ทฐ์— ์ „๋‹ฌํ•œ๋‹ค.
addAttribute() ๋ฉ”์†Œ๋“œ๋กœ ๋ชจ๋ธ์— ๊ฐ์ฒด๋ฅผ ๋“ฑ๋กํ•œ๋‹ค.
model.addAttribute("์†์„ฑ๋ช…", ๊ฐ’); //
Java
๋ณต์‚ฌ
โ€ข
view.jsp ์—์„œ ${ } ํ‘œํ˜„์–ธ์–ด๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.
${์†์„ฑ๋ช…}
Java
๋ณต์‚ฌ
โ€ข
์†์„ฑ๊ฐ’์ด ๊ฐ์ฒด์ธ ๊ฒฝ์šฐ, getter ๋ฉ”์†Œ๋“œ๊ฐ€ ์ •์˜๋˜์–ด ์žˆ์œผ๋ฉด ๊ฐ์ฒด.๋ณ€์ˆ˜ ํ˜•ํƒœ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.
${์†์„ฑ๋ช….๋ณ€์ˆ˜}
Java
๋ณต์‚ฌ
๋ณ€์ˆ˜๋ช…์„ ์ƒ๋žตํ•˜๋ฉด ๊ฐ์ฒด๋ช…๊ณผ ์ผ์น˜ํ•˜๋Š” ์ด๋ฆ„์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.
model.addAttribute(๊ฐ์ฒด๋ช…);
Java
๋ณต์‚ฌ
โ€ข
view.jsp
${๊ฐ์ฒด๋ช…}
Java
๋ณต์‚ฌ
โ€ข
ModelController.java
/** * ์š”์ฒญ ๊ฒฝ๋กœ : /model/person * @param model * @param person * @return * * ์ปจํŠธ๋กค๋Ÿฌ ๋ฉ”์†Œ๋“œ์—์„œ ๋งค๊ฐœ๋ณ€์ˆ˜์— ๊ฐ์ฒด๋ฅผ ์ง€์ •ํ•˜๋ฉด, * * ์ž๋™ ๊ฐ์ฒด ์ƒ์„ฑ : ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ์Šคํ”„๋ง์—์„œ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ด์„œ ์ฃผ์ž…ํ•ด์ค€๋‹ค. * * ์ž๋™ ๋ฐ”์ธ๋”ฉ : ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐ’์„ ๊ฐ์ฒด์˜ ๋ณ€์ˆ˜์— ์ž๋™์œผ๋กœ ๋งคํ•‘ํ•ด์ค€๋‹ค. * ex) /model/person?name=ALOHA&age=20 * Person.name <---- "ALOHA" * Person.age <---- 20 */ @RequestMapping("/model/person") // method: GET(๊ธฐ๋ณธ๊ฐ’) public String person(Model model, Person person) { // Model ์ธํ„ฐํŽ˜์ด์Šค์˜ addAttribute() ๋ฉ”์†Œ๋“œ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋“ฑ๋กํ•˜์—ฌ, ๋ทฐ์— ์ „๋‹ฌํ•œ๋‹ค. // Model // : ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ๋“ฑ๋กํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ทฐ์— ์ „๋‹ฌํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค // Person person = new Person(); // person.setName("๊น€์กฐ์€"); // person.setAge(20); // addAttribute("๋ณ€์ˆ˜๋ช…", ๊ฐ์ฒด) ๋ฉ”์†Œ๋“œ๋กœ ๋ชจ๋ธ์— ๊ฐ์ฒด๋ฅผ ๋“ฑ๋กํ•œ๋‹ค. // model.addAttribute("person", person); model.addAttribute(person); // ๋ณ€์ˆ˜๋ช…์„ ์ƒ๋žตํ•˜๋ฉด ๊ฐ์ฒด๋ช…๊ณผ ์ผ์น˜ํ•˜๋Š” ์ด๋ฆ„์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. // view ์—์„œ ${} (ํ‘œํ˜„์–ธ์–ด) ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. // ${person.name}, ${person.age} // getter ๋ฉ”์†Œ๋“œ๊ฐ€ ์ •์˜๋˜์–ด ์žˆ์–ด์•ผ ์œ„์™€๊ฐ™์ด ๋ทฐ์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. return "model/person"; // view : model/person.jsp }
Java
๋ณต์‚ฌ
โ€ข
model/person.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>/model/person</title> </head> <body> <h1>์ด๋ฆ„ : ${person.name}</h1> <h1>๋‚˜์ด : ${person.age}</h1> <hr> <form action="${ pageContext.request.contextPath }/model/person" method="POST"> <input type="text" name="name" value="${person.name}" /> <br> <input type="text" name="age" value="${person.age}" /> <br> <input type="submit" value="๋“ฑ๋ก" /> </form> </body> </html>
HTML
๋ณต์‚ฌ

@ModelAttribute

๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ชจ๋ธ์— ์ž๋™์œผ๋กœ ๋“ฑ๋กํ•ด์ฃผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜
/** * ์š”์ฒญ ๊ฒฝ๋กœ : /model/person2?name=๊น€์กฐ์€&age=20 * * ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ๋ณ€์ˆ˜๋ช…๋“ค์„ ๊ฐ์ฒด์˜ ํ•„๋“œ(๋ฉค๋ฒ„๋ณ€์ˆ˜)๋กœ ์ž๋™์œผ๋กœ ๋งคํ•‘ํ•ด์ค€๋‹ค. * @param person * @return */ @RequestMapping("/model/person2") public String person2(@ModelAttribute Person person) { // @ModelAttribute : ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ชจ๋ธ์— ์ž๋™์œผ๋กœ ๋“ฑ๋กํ•ด์ฃผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜ // model.addAttribute("person", person); return "model/person"; // view : model/person.jsp }
Java
๋ณต์‚ฌ

@RequestParam

์š”์ฒญ ๋งค๊ฐœ๋ณ€์ˆ˜(parameter)๋ฅผ ๋ฉ”์†Œ๋“œ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ”์ธ๋”ฉํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜
/** * ์š”์ฒญ ๊ฒฝ๋กœ : /model/person * method : POST * * @param person * @return */ @RequestMapping(value = "/model/person", method = RequestMethod.POST) public String personPost( Model model , @RequestParam("name") String personName , @RequestParam("age") int personAge ) { // @RequestParam("์š”์ฒญํŒŒ๋ผ๋ฏธํ„ฐ๋ช…") ๋ฐ์ดํ„ฐํƒ€์ž… ๋ฉ”์†Œ๋“œ๋งค๊ฐœ๋ณ€์ˆ˜๋ช… // : ์š”์ฒญ ๋งค๊ฐœ๋ณ€์ˆ˜(parameter)๋ฅผ ๋ฉ”์†Œ๋“œ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ”์ธ๋”ฉํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜ // * ์š”์ฒญํŒŒ๋ผ๋ฏธํ„ฐ๋ช… = ๋ฉ”์†Œ๋“œ๋งค๊ฐœ๋ณ€์ˆ˜๋ช… ์ผ์น˜ํ•˜๋ฉด, ์ƒ๋žต๊ฐ€๋Šฅ Person person = new Person(); person.setName(personName); person.setAge(personAge); // forward ๋ฐฉ์‹์œผ๋กœ ํŽ˜์ด์ง€ ์ด๋™ ์‹œ, ๋ชจ๋ธ์— ๋ฐ์ดํ„ฐ ์‚ฌ์šฉ๊ฐ€๋Šฅ model.addAttribute(person); return "model/person"; // view : model/person.jsp }
Java
๋ณต์‚ฌ

RedirectAttributes

๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ๋ฐฉ์‹์œผ๋กœ ํŽ˜์ด์ง€ ์ด๋™ ์‹œ, ์ผํšŒ์„ฑ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค
/** * ์š”์ฒญ ๊ฒฝ๋กœ : /model/person * method : POST * * @param person * @return */ @RequestMapping(value = "/person", method = RequestMethod.POST) public String personPost(Model model, Person person, RedirectAttributes rttr) { // RedirectAttributes ์ธํ„ฐํŽ˜์ด์Šค // : ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ๋ฐฉ์‹์œผ๋กœ ํŽ˜์ด์ง€ ์ด๋™ ์‹œ, ์ผํšŒ์„ฑ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค // forward ๋ฐฉ์‹์œผ๋กœ ํŽ˜์ด์ง€ ์ด๋™ ์‹œ, ๋ชจ๋ธ์— ๋ฐ์ดํ„ฐ ์‚ฌ์šฉ๊ฐ€๋Šฅ model.addAttribute(person); // redirect ๋ฐฉ์‹์œผ๋กœ ํŽ˜์ด์ง€ ์ด๋™ ์‹œ, // RedirectAttributes ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด์„œ ์ผํšŒ์„ฑ์œผ๋กœ ๋ฐ์ดํ„ฐ ์ „๋‹ฌ ๊ฐ€๋Šฅ rttr.addFlashAttribute("person", person); // ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ : redirect:์š”์ฒญ๊ฒฝ๋กœ // * ์ตœ์ดˆ ์š”์ฒญ ๊ฐ์ฒด๋Š” ์‚ฌ๋ผ์ง„๋‹ค. return "redirect:/model/person"; // view : model/person.jsp }
Java
๋ณต์‚ฌ

์‘๋‹ต ์ฒ˜๋ฆฌ

โ€ข
void
โ€ข
String
โ€ข
ModelAndView
โ€ข
ํด๋ž˜์Šค
โ€ข
์ปฌ๋ ‰์…˜
โ€ข
ResponseEntity

ResponseController.java

@Controller //@RequestMapping("/response") public class ResponseController { private static final Logger logger = LoggerFactory.getLogger(ResponseController.class); @Autowired private BoardService boardService; // (๋‚˜๋จธ์ง€ ์ฝ”๋“œ๋Š” ์•„๋ž˜ ์ฝ”๋“œ๋ธ”๋Ÿญ ํ•˜๋‚˜์”จ }
Java
๋ณต์‚ฌ

void

์š”์ฒญ ๊ฒฝ๋กœ์™€ ๊ฐ™์€ ๊ฒฝ๋กœ์˜ view ์‘๋‹ตํ•œ๋‹ค.
/** * ์š”์ฒญ ๊ฒฝ๋กœ : /response/index * ์‘๋‹ต : /response/index.jsp */ @RequestMapping("/response/index") public void response() { logger.info("void ํƒ€์ž… - /response/index"); logger.info("/response/index.jsp ๋ทฐ๋ฅผ ์‘๋‹ต"); }
Java
๋ณต์‚ฌ

String

๋ทฐ ์ด๋ฆ„์„ ์ง€์ •ํ•˜์—ฌ ์‘๋‹ตํ•œ๋‹ค.
/** * ์š”์ฒญ ๊ฒฝ๋กœ : /response/view * ์‘๋‹ต : /response/index.jsp * @return */ @RequestMapping("/response/view") public String responseView() { logger.info("String ํƒ€์ž… - /response/index"); logger.info("/response/index.jsp ๋ทฐ๋ฅผ ์‘๋‹ต"); logger.info("view ์ด๋ฆ„์„ ๋ฐ˜ํ™˜๊ฐ’์œผ๋กœ ์ง€์ •"); return "response/index"; }
Java
๋ณต์‚ฌ

ModelAndView

๋ทฐ์™€ ๋ชจ๋ธ ๋ฐ์ดํ„ฐ๋ฅผ ์ง€์ •ํ•˜์—ฌ ํ•จ๊ป˜ ๋ฐ˜ํ™˜ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์Šคํ”„๋งํ”„๋ ˆ์ž„์›Œํฌ ํด๋ž˜์Šค
/** * ์š”์ฒญ ๊ฒฝ๋กœ : /response/model/view * ์‘๋‹ต : /response/index.jsp * @return */ @RequestMapping("/response/model/view") public ModelAndView responseModeAndView() { // ModelAndView // ๋ทฐ์™€ ๋ชจ๋ธ ๋ฐ์ดํ„ฐ๋ฅผ ์ง€์ •ํ•˜์—ฌ ํ•จ๊ป˜ ๋ฐ˜ํ™˜ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์Šคํ”„๋งํ”„๋ ˆ์ž„์›Œํฌ ํด๋ž˜์Šค logger.info("ModelAndView ํƒ€์ž… - /response/model/view"); logger.info("/response/index.jsp ๋ทฐ๋ฅผ ์‘๋‹ต"); logger.info("๋ชจ๋ธ๊ณผ ๋ทฐ๋ฅผ ModelAndView ๊ฐ์ฒด์— ์ง€์ •ํ•˜์—ฌ ์‘๋‹ต"); ModelAndView mv = new ModelAndView(); // ๋ทฐ์ด๋ฆ„ ์ง€์ • mv.setViewName("/response/index"); // view : /response/index.jsp // ๋ชจ๋ธ ๋“ฑ๋ก Board board = new Board("์ œ๋ชฉ","์ž‘์„ฑ์ž","๋‚ด์šฉ"); mv.addObject("board", board); mv.addObject("message", "ModelAndView ์ปจํŠธ๋กค๋Ÿฌ ์‘๋‹ต..."); // model : board, message return mv; }
Java
๋ณต์‚ฌ

ํด๋ž˜์Šค

์ปจํŠธ๋กค๋Ÿฌ ๋ฉ”์†Œ๋“œ์— ํด๋ž˜์Šค๋ฅผ ๋ฐ˜ํ™˜ํƒ€์ž…์œผ๋กœ ์ง€์ •ํ•˜๋Š” ๊ฒฝ์šฐ, ์ผ๋ฐ˜์ ์„ JSON ๋˜๋Š” XML ๋ฐ์ดํ„ฐ ํ˜•์‹์œผ๋กœ ์‘๋‹ตํ•œ๋‹ค.
/** * ์š”์ฒญ ๊ฒฝ๋กœ : /response/data/board * ์‘๋‹ต : board (JSON/XML) * @ResponseBody : ์‘๋‹ตํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์‘๋‹ต ๋ฉ”์‹œ์ง€์˜ body(๋ณธ๋ฌธ) ์— ์ง€์ •ํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜ * @return */ @ResponseBody @RequestMapping("/response/data/board") public Board responseBoard() { Board board = new Board("์ œ๋ชฉ","์ž‘์„ฑ์ž","๋‚ด์šฉ"); return board; }
Java
๋ณต์‚ฌ
Chrome ๋ธŒ๋ผ์šฐ์ €์˜ ๊ฒฝ์šฐ Accept ํ—ค๋”

Accept

text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
HTML
๋ณต์‚ฌ
Accept ํ—ค๋” ์ •๋ณด๊ฐ€ html, xml ์šฐ์„ ์ˆœ์œ„๋กœ ๋˜์–ด ์žˆ์–ด์„œ, ๋ณ„๋‹ค๋ฅธ ํ—ค๋” ์ •๋ณด ์„ค์ • ์—†์ด ์š”์ฒญํ•˜๋ฉด ํด๋ž˜์Šค๋ฅผ ์‘๋‹ตํ•˜๋Š” ๊ฒฝ์šฐ๋Š” Accept ํ—ค๋” ์ •๋ณด์— ๋งž์ถฐ ์šฐ์„ ์ˆœ์œ„์— ๋”ฐ๋ผ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” ํƒ€์ž…์œผ๋กœ ์‘๋‹ตํ•œ๋‹ค.

์ปฌ๋ ‰์…˜

์ปจํŠธ๋กค๋Ÿฌ ๋ฉ”์†Œ๋“œ์— ์ปฌ๋ ‰์…˜์„ ๋ฐ˜ํ™˜ํƒ€์ž…์œผ๋กœ ์ง€์ •ํ•˜๋Š” ๊ฒฝ์šฐ, ์ผ๋ฐ˜์ ์„ JSON ๋˜๋Š” XML ๋ฐ์ดํ„ฐ ํ˜•์‹์œผ๋กœ ์‘๋‹ตํ•œ๋‹ค.
/** * ๋ธŒ๋ผ์šฐ์ €์—์„œ Accept ํ—ค๋”์˜ ๊ฐ’์ด ์šฐ์„ ์ˆœ์œ„ * - text/html * - application/xhtml+xml * - application/xml * - ... * @return * @throws Exception */ @ResponseBody // @RequestMapping("/response/data/board/list") @RequestMapping(value = "/response/data/board/list", produces = "application/json") public List<Board> responseBoardList() throws Exception { // produces = "application/json" // - Accept:application/xml ์œผ๋กœ ์š”์ฒญ์ด ์™€๋„, json ์œผ๋กœ ์‘๋‹ตํ•  ์ˆ˜ ์žˆ๋‹ค. List<Board> boardList = boardService.list(); return boardList; }
Java
๋ณต์‚ฌ
@ResponseBody // @RequestMapping(value = "/resopnse/data/map") @RequestMapping(value = "/response/data/map", produces = "application/json") public Map<String, Board> responseMap() throws Exception { Map<String, Board> map = new HashMap<String, Board>(); map.put("board1", new Board("b1", "์ œ๋ชฉ1","์ž‘์„ฑ์ž1","๋‚ด์šฉ1")); map.put("board2", new Board("b2", "์ œ๋ชฉ2","์ž‘์„ฑ์ž2","๋‚ด์šฉ2")); map.put("board3", new Board("b3", "์ œ๋ชฉ3","์ž‘์„ฑ์ž3","๋‚ด์šฉ3")); return map; }
Java
๋ณต์‚ฌ

ResponseEntity

ResponseEntity<Void>

@ResponseBody @RequestMapping("/response/data/entity/void") public ResponseEntity<Void> responseEntityVoid() { // ResponseEntity // : ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์‘๋‹ต ํ—ค๋”,๋ณธ๋ฌธ,์ƒํƒœ์ฝ”๋“œ ๋“ฑ์„ ์บก์Аํ™”ํ•˜๋Š” ๊ฐ์ฒด // ResponseEntity<Void> // : ํ—ค๋”์ •๋ณด, ์ƒํƒœ์ฝ”๋“œ๋ฅผ ์ง€์ •ํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. // HttpStatus ์—ด๊ฑฐํƒ€์ž… // : ์ƒํƒœ์ฝ”๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์Šคํ”„๋งํ”„๋ ˆ์ž„์›ค์˜ ์—ด๊ฑฐํƒ€์ž… // - OK : 200 // - NOT_FOUND : 404 // - INTERNAL_SERVER_ERROR : 500 return new ResponseEntity<Void>(HttpStatus.OK); }
Java
๋ณต์‚ฌ

ResponseEntity<String>

@ResponseBody @RequestMapping("/response/data/entity/string") public ResponseEntity<String> responseEntityString() { // new ResponseEntity<๋ฐ˜ํ™˜ํƒ€์ž…>(์‘๋‹ต๋ฉ”์‹œ์ง€, ์ƒํƒœ์ฝ”๋“œ); return new ResponseEntity<String>("SUCCESS", HttpStatus.OK); }
Java
๋ณต์‚ฌ

ResponseEntity<Board>

@ResponseBody @RequestMapping("/response/data/entity/board") public ResponseEntity<Board> responseEntityBoard() { Board board = new Board("b01","์ œ๋ชฉ","์ž‘์„ฑ์ž","๋‚ด์šฉ"); return new ResponseEntity<Board>(board, HttpStatus.OK); }
Java
๋ณต์‚ฌ

ResponseEntity<List<Board>>

@ResponseBody @RequestMapping("/response/data/entity/board/list") public ResponseEntity<List<Board>> responseEntityBoardList() throws Exception { List<Board> boardList = boardService.list(); // return new ResponseEntity<>(boardList, HttpStatus.OK); // <> ์ƒ๋žต๊ฐ€๋Šฅ return new ResponseEntity<List<Board>>(boardList, HttpStatus.OK); }
Java
๋ณต์‚ฌ

ResponseEntity<Map<String, Board>>

@ResponseBody @RequestMapping("/response/data/entity/map") public ResponseEntity<Map<String, Board>> responseEntityBoardMap() throws Exception { List<Board> boardList = boardService.list(); Map<String, Board> map = new HashMap<String, Board>(); int i = 1; for (Board board : boardList) { map.put("board" + i++, board); } return new ResponseEntity<>(map, HttpStatus.OK); }
Java
๋ณต์‚ฌ

ResponseEntity<byte[]>

/** * ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ * * @return * @throws Exception */ @ResponseBody @RequestMapping("/response/data/file") public ResponseEntity<byte[]> responseFile(HttpServletRequest request) throws Exception { String path = request.getSession().getServletContext().getRealPath("/WEB-INF/upload/test.png"); logger.info("path : " + path); // ํŒŒ์ผ ๊ฒฝ๋กœ // String filePath = "E:\\TJE\\UPLOAD\\test.jpg"; String filePath = request.getSession().getServletContext().getRealPath("/WEB-INF/upload/test.png"); String fileName = "test.png"; // ํ—ค๋”์ •๋ณด HttpHeaders headers = new HttpHeaders(); headers.setContentType( MediaType.IMAGE_JPEG ); // ์ด๋ฏธ์ง€๋กœ ์‘๋‹ต // headers.setContentType( MediaType.APPLICATION_OCTET_STREAM); // ์ผ๋ฐ˜ ํ”„๋กœ๊ทธ๋žจ ์‘๋‹ต // headers.add("ํ—ค๋”๋ช…", "๊ฐ’") // Content-Disposition // - inline : ์›นํŽ˜์ด์ง€์—์„œ ์ถœ๋ ฅ(๊ธฐ๋ณธ๊ฐ’) // - attachment : ์ฒจ๋ถ€ํŒŒ์ผ (๋‹ค์šด๋กœ๋“œ) headers.add("Content-Disposition", "attachment; filename=" + fileName); // ๋‹ค์šด๋กœ๋“œ ์—ฌ๋ถ€, ํŒŒ์ผ๋ช… ์ง€์ • byte[] fileData = null; try { FileInputStream fis = new FileInputStream(filePath); // commons-io ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ // toByteArray() : ํŒŒ์ผ์„ ๋ฐ”์ดํŠธ์ฝ”๋“œ๋กœ ๋ณ€ํ™˜ fileData = IOUtils.toByteArray(fis); } catch (Exception e) { // TODO: handle exception } // new ResponseEntity<๋ฐ˜ํ™˜ํƒ€์ž…>(์‘๋‹ต๋ฉ”์‹œ์ง€, ํ—ค๋”,์ƒํƒœ์ฝ”๋“œ); return new ResponseEntity<byte[]>(fileData, headers, HttpStatus.OK); }
Java
๋ณต์‚ฌ

์š”์ฒญ ์ฒ˜๋ฆฌ

โ€ข
์ฃผ์š” ์ปจํŠธ๋กค๋Ÿฌ ๋ฉ”์†Œ๋“œ ๋งค๊ฐœ๋ณ€์ˆ˜
โ—ฆ
Model
โ—ฆ
ํด๋ž˜์Šค
โ—ฆ
์ปฌ๋ ‰์…˜
โ—ฆ
HttpServletRequest
โ—ฆ
HttpServletResponse
โ—ฆ
RedirectAttribute
โ€ข
์ฃผ์š” ์š”์ฒญ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์–ด๋…ธํ…Œ์ด์…˜
โ—ฆ
@RequestParam
โ—ฆ
@PathVariable
โ—ฆ
@RequestHeader
โ—ฆ
@RequestBody
โ—ฆ
@CookieValue
โ€ข
ํผ ์š”์ฒญ ์ฒ˜๋ฆฌ
โ—ฆ
checkbox
โ—ฆ
date
โ€ข
ํŒŒ์ผ ์—…๋กœ๋“œ
โ€ข
AJAX ํŒŒ์ผ ์—…๋กœ๋“œ

์ฃผ์š” ์ปจํŠธ๋กค๋Ÿฌ ๋ฉ”์†Œ๋“œ ๋งค๊ฐœ๋ณ€์ˆ˜

โ€ข
Model
โ€ข
ํด๋ž˜์Šค
โ€ข
์ปฌ๋ ‰์…˜
โ€ข
HttpServletRequest
โ€ข
HttpServletResponse
โ€ข
RedirectAttribute
๋งค๊ฐœ๋ณ€์ˆ˜
์„ค๋ช…
Model
์ปจํŠธ๋กค๋Ÿฌ์—์„œ ๋ทฐ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•œ ์ธํ„ฐํŽ˜์ด์Šค
ํด๋ž˜์Šค
์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ฐ์ฒด๋กœ ๋ฐ”์ธ๋”ฉํ•˜์—ฌ ์ฒ˜๋ฆฌํ•˜๋Š” ์ปค๋งจ๋“œ ๊ฐ์ฒด
์ปฌ๋ ‰์…˜
List, Set, Map ๋“ฑ์˜ ์ปฌ๋ ‰์…˜ ํƒ€์ž…์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌ
HttpServletRequest
HTTP ์š”์ฒญ ์ •๋ณด๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์„œ๋ธ”๋ฆฟ ์š”์ฒญ ๊ฐ์ฒด
HttpServletResponse
HTTP ์‘๋‹ต ์ •๋ณด๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์„œ๋ธ”๋ฆฟ ์‘๋‹ต ๊ฐ์ฒด
RedirectAttribute
๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ์ฒด

์ฃผ์š” ์š”์ฒญ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์–ด๋…ธํ…Œ์ด์…˜

โ€ข
@RequestParam
โ€ข
@PathVariable
โ€ข
@RequestHeader
โ€ข
@RequestBody
โ€ข
@CookieValue
์–ด๋…ธํ…Œ์ด์…˜
์„ค๋ช…
@RequestParam
HTTP ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฉ”์†Œ๋“œ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ”์ธ๋”ฉ. URL์˜ ์ฟผ๋ฆฌ ์ŠคํŠธ๋ง์ด๋‚˜ ํผ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌ
@PathVariable
URL ๊ฒฝ๋กœ์˜ ์ผ๋ถ€๋ฅผ ๋ฉ”์†Œ๋“œ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ”์ธ๋”ฉ. RESTful API์—์„œ ์ฃผ๋กœ ์‚ฌ์šฉ
@RequestHeader
HTTP ์š”์ฒญ ํ—ค๋”๋ฅผ ๋ฉ”์†Œ๋“œ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ”์ธ๋”ฉ
@RequestBody
HTTP ์š”์ฒญ ๋ณธ๋ฌธ์„ ๋ฉ”์†Œ๋“œ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ”์ธ๋”ฉ. JSON/XML ๋“ฑ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜
@CookieValue
HTTP ์ฟ ํ‚ค ๊ฐ’์„ ๋ฉ”์†Œ๋“œ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ”์ธ๋”ฉ

ํผ ์š”์ฒญ ์ฒ˜๋ฆฌ

โ€ข
checkbox
โ€ข
date

ํŒŒ์ผ ์—…๋กœ๋“œ

AJAX ํŒŒ์ผ ์—…๋กœ๋“œ

์š”์ฒญ ํ—ค๋” ๊ฐ€์ ธ์˜ค๊ธฐ

/** * ์š”์ฒญ ํ—ค๋” ๊ฐ€์ ธ์˜ค๊ธฐ * @return * * @RequestHeader("ํ—ค๋”๋ช…") ํƒ€์ž… ๋ณ€์ˆ˜๋ช… */ @ResponseBody @RequestMapping(value = "/header", method = RequestMethod.GET) public String header(@RequestHeader("Accept") String accept ,@RequestHeader("User-Agent") String userAgent ,HttpServletRequest request) { // @RequestHeader ๋ฅผ ํ†ตํ•œ ํ—ค๋” ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ logger.info("[GET] - /request/header"); logger.info("@RequestHeader ๋ฅผ ํ†ตํ•œ ํ—ค๋” ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ"); logger.info("Accept - " + accept); logger.info("User-Agent - " + userAgent); // request ๊ฐ์ฒด๋กœ๋ถ€ํ„ฐ ํ—ค๋” ๊ฐ€์ ธ์˜ค๊ธฐ String requestAccept = request.getHeader("Accept"); String requestUserAgent = request.getHeader("User-Agent"); logger.info("request ๊ฐ์ฒด๋กœ๋ถ€ํ„ฐ ํ—ค๋” ๊ฐ€์ ธ์˜ค๊ธฐ"); logger.info("Accept - " + requestAccept); logger.info("User-Agent - " + requestUserAgent); return "SUCCESS"; }
Java
๋ณต์‚ฌ

๊ธฐ๋ณธ ์š”์ฒญ ์ฒ˜๋ฆฌ

โ€ข
์š”์ฒญ ํ—ค๋” ๊ฐ€์ ธ์˜ค๊ธฐ
โ€ข
์š”์ฒญ ๋ณธ๋ฌธ ๊ฐ€์ ธ์˜ค๊ธฐ

RequestController.java

@Controller // Controller ์ง€์ •ํ•˜๊ณ  ๋นˆ ๋“ฑ๋ก @RequestMapping("/request") // [ํด๋ž˜์Šค ๋ ˆ๋ฒจ ์š”์ฒญ๊ฒฝ๋กœ ๋งคํ•‘] "/request" ์š”์ฒญ ๊ฒฝ๋กœ๋กœ ๋งคํ•‘ public class RequestController { // log ๊ฐ์ฒด private static final Logger logger = LoggerFactory.getLogger(RequestController.class); }
Java
๋ณต์‚ฌ

์š”์ฒญ ํ—ค๋” ๊ฐ€์ ธ์˜ค๊ธฐ

/** * ์š”์ฒญ ํ—ค๋” ๊ฐ€์ ธ์˜ค๊ธฐ * @return * * @RequestHeader("ํ—ค๋”๋ช…") ํƒ€์ž… ๋ณ€์ˆ˜๋ช… */ @ResponseBody @RequestMapping(value = "/header", method = RequestMethod.GET) public String header(@RequestHeader("Accept") String accept ,@RequestHeader("User-Agent") String userAgent ,HttpServletRequest request) { // @RequestHeader ๋ฅผ ํ†ตํ•œ ํ—ค๋” ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ logger.info("[GET] - /request/header"); logger.info("@RequestHeader ๋ฅผ ํ†ตํ•œ ํ—ค๋” ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ"); logger.info("Accept - " + accept); logger.info("User-Agent - " + userAgent); // request ๊ฐ์ฒด๋กœ๋ถ€ํ„ฐ ํ—ค๋” ๊ฐ€์ ธ์˜ค๊ธฐ String requestAccept = request.getHeader("Accept"); String requestUserAgent = request.getHeader("User-Agent"); logger.info("request ๊ฐ์ฒด๋กœ๋ถ€ํ„ฐ ํ—ค๋” ๊ฐ€์ ธ์˜ค๊ธฐ"); logger.info("Accept - " + requestAccept); logger.info("User-Agent - " + requestUserAgent); return "SUCCESS"; }
Java
๋ณต์‚ฌ

์š”์ฒญ ๋ณธ๋ฌธ ๊ฐ€์ ธ์˜ค๊ธฐ

/** * ์š”์ฒญ ๋ณธ๋ฌธ ๊ฐ€์ ธ์˜ค๊ธฐ * @param board * @return * * @RequestBody * : HTTP ์š”์ฒญ ๋ฉ”์‹œ์ง€์˜ ๋ณธ๋ฌธ(body) ๋‚ด์šฉ์„ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜ * ์ฃผ๋กœ, ํด๋ผ์ด์–ธํŠธ์—์„œ json ํ˜•์‹์œผ๋กœ ๋ณด๋‚ธ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค. * * ์ƒ๋žต๊ฐ€๋Šฅ (์ฃผ๋กœ ์ƒ๋žตํ•˜๊ณ  ์“ด๋‹ค.) * * 415 ์—๋Ÿฌ - ์ง€์›๋˜์ง€ ์•Š๋Š” ๋ฏธ๋””์–ด ํƒ€์ž… * (Unsupported Media Type) * : ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ณด๋‚ธ ์ปจํ…์ธ  ํƒ€์ž…์˜ ์š”์ฒญ์„ ์„œ๋ฒ„๊ฐ€ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์—†์„ ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ * [ํด๋ผ์ด์–ธํŠธ] ( application/x-www-form-urlencoded ) * โ†“ * [ ์„œ ๋ฒ„ ] ( application/json ) * * @RequestBody ๋ฅผ ์“ฐ๋ฉด, ๋ณธ๋ฌธ์˜ ์ปจํ…์ธ  ํƒ€์ž…์„ application/json ์„ ๊ธฐ๋ณธ์œผ๋กœ ์ง€์ • * * * ๋น„๋™๊ธฐ ๋˜๋Š” thunder client ๋กœ ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅ * Content-Type : application/json * body { "title" : "์ œ๋ชฉ", "writer" : "์ž‘์„ฑ์ž", "content" : "๋‚ด์šฉ" } */ @ResponseBody @RequestMapping(value = "/body", method = RequestMethod.POST) public String requestBody(@RequestBody Board board) { logger.info("[POST] - /request/body"); logger.info(board.toString()); return "SUCCESS"; }
Java
๋ณต์‚ฌ
form ์š”์ฒญ์ธ ๊ฒฝ์šฐ ํŒŒ๋ผ๋ฏธํ„ฐ ์ด๋ฆ„๊ณผ ๊ฐ์ฒด์˜ ํ•„๋“œ๋ช…์„ ๋งค์นญํ•˜์—ฌ Board board ํ˜•์‹์œผ๋กœ ๊ฐ์ฒด๋ฅผ ์ž๋™ ๋ฐ”์ธ๋”ฉ ํ•ฉ๋‹ˆ๋‹ค.
JSON ์š”์ฒญ์ธ ๊ฒฝ์šฐ, @RequestBody Board board ํ˜•์‹์œผ๋กœ ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ช…์‹œํ•˜์—ฌ JSON ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๋ฐ”์ธ๋”ฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
์š”์ฒญ ์œ ํ˜•
์ฒ˜๋ฆฌ ๋ฐฉ์‹
์˜ˆ์‹œ
Form ์š”์ฒญ
ํŒŒ๋ผ๋ฏธํ„ฐ ์ด๋ฆ„๊ณผ ๊ฐ์ฒด์˜ ํ•„๋“œ๋ช…์„ ์ž๋™ ๋งค์นญํ•˜์—ฌ ๋ฐ”์ธ๋”ฉ
public String method(Board board) { ... }
JSON ์š”์ฒญ
@RequestBody ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ JSON์„ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜
public String method(@RequestBody Board board) { ... }

ํŒŒ์ผ ์—…๋กœ๋“œ

โ€ข
pom.xml
<!-- commons-io --> <!-- ํŒŒ์ผ ์—…๋กœ๋“œ/๋‹ค์šด๋กœ๋“œ๋ฅผ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.11.0</version> </dependency> <!-- annotation --> <!-- @Resource ์–ด๋…ธํ…Œ์ด์…˜ ๋“ฑ --> <dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> <version>1.3.2</version> </dependency>
XML
๋ณต์‚ฌ
โ€ข
web.xml
<!-- Processes application requests --> <servlet> <servlet-name>appServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- โœ… ํŒŒ์ผ์—…๋กœ๋“œ ๊ธฐ๋Šฅ ํ™œ์„ฑํ™” --> <multipart-config /> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>appServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
XML
๋ณต์‚ฌ
โ€ข
servlet-context.xml
<!-- โœ… MultipartResolver ๋นˆ ๋“ฑ๋ก --> <beans:bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver"> </beans:bean> <!-- โœ… ์—…๋กœ๋“œ ๊ฒฝ๋กœ ๋นˆ ๋“ฑ๋ก --> <beans:bean id="uploadPath" class="java.lang.String"> <beans:constructor-arg value="C:\\upload"> </beans:constructor-arg> </beans:bean>
XML
๋ณต์‚ฌ
โ€ข
file.jsp
<h3>/file.jsp/h3> <form action="${ pageContext.request.contextPath }/file" method="POST" enctype="multipart/form-data"> <input type="file" name="file" /> <br> <input type="submit" value="๋“ฑ๋ก" /> </form>
HTML
๋ณต์‚ฌ
โ€ข
Controller.java
@Resource(name = "uploadPath") private String uploadPath; // ํŒŒ์ผ ์—…๋กœ๋“œ @ResponseBody @RequestMapping("/file") public String fileUpload(MultipartFile file) throws IOException { logger.info("/file"); logger.info("uploadPath : " + uploadPath); if( file == null ) return "FAIL"; logger.info("originalFileName : " + file.getOriginalFilename()); logger.info("size : " + file.getSize()); logger.info("contentType : " + file.getContentType()); byte[] fileData = file.getBytes(); // ํŒŒ์ผ ์—…๋กœ๋“œ String filePath = uploadPath; String fileName = file.getOriginalFilename(); File uploadFile = new File(filePath, fileName); FileCopyUtils.copy(fileData, uploadFile); // ํŒŒ์ผ ์—…๋กœ๋“œ return "SUCCESS"; }
Java
๋ณต์‚ฌ

AJAX ํŒŒ์ผ ์—…๋กœ๋“œ

ajax.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h1>AJAX ํŒŒ์ผ ์—…๋กœ๋“œ</h1> <form action="${ pageContext.request.contextPath }/request/ajax" method="POST" enctype="multipart/form-data"> <table class="board"> <tr> <td class="label">์ œ๋ชฉ</td> <td class="data"> <input type="text" name="title" id="title" class="input-text"> </td> </tr> <tr> <td class="label">์ž‘์„ฑ์ž</td> <td class="data"> <input type="text" name="writer" id="writer" class="input-text"> </td> </tr> <tr> <td class="label">๋‚ด์šฉ</td> <td class="data"> <textarea name="content" id="content" cols="30" rows="10" class="input-textarea"></textarea> </td> </tr> <tr> <td class="label">ํŒŒ์ผ</td> <td class="data"> <input type="file" name="file" id="file" multiple> </td> </tr> </table> <div class="btn-box"> <div class="item"> <a href="javascript:;" class="btn" id="btn-insert">๋“ฑ๋ก</a> </div> </div> </form> <!-- script --> <script src="https://code.jquery.com/jquery-3.7.0.min.js"></script> <script> // ๋“ฑ๋ก ๋ฒ„ํŠผ - ํด๋ฆญ ์ด๋ฒคํŠธ $('#btn-insert').on('click', function() { // ๋“ฑ๋ก ์š”์ฒญ let formData = new FormData() // ํผ ๋ฐ์ดํ„ฐ ๊ฐ์ฒด let title = $('#title').val() let writer = $('#writer').val() let content = $('#content').val() formData.append('title', title) formData.append('writer', writer) formData.append('content', content) // ํŒŒ์ผ ์ž…๋ ฅ ๊ฐ€์ ธ์˜ค๊ธฐ let file = $('#file')[0] let files = file.files // ํŒŒ์ผ ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€ for (let i = 0; i < files.length; i++) { formData.append('file', files[i]) } let url = 'http://localhost:8080/spring/request/ajax' $.ajax({ url : url, type : 'POST', data : formData, contentType : false, processData : false, // ๋ฐ์ดํ„ฐ ์ปจํ…์ธ  ํƒ€์ž… ์ž๋™ ๋ณ€ํ™˜ ์—ฌ๋ถ€ // ๊ธฐ๋ณธ๊ฐ’(true) // true -> contentType : application/x-www-form-urlencoded // false -> contentType : ๋ฐ์ดํ„ฐ๋ฅผ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๊ณ  ์ง์ ‘ ์ง€์ • success : function(response) { if( response == 'SUCCESS' ){ alert('๋“ฑ๋ก์ด ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.') } }, error : function(request, status, error){ alert("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error); } }) }) </script> </body> </html>
HTML
๋ณต์‚ฌ

์ปจํŠธ๋กค๋Ÿฌ ๋ฉ”์†Œ๋“œ

@ResponseBody @RequestMapping(value = "/ajax", method = RequestMethod.POST) public String ajaxUploadPost(Board board) throws IOException { logger.info("/request/ajax"); logger.info("uploadPath : " + uploadPath); logger.info(board.toString()); List<MultipartFile> fileList = board.getFile(); if( fileList == null ) return "FAIL"; if( !fileList.isEmpty() ) for (MultipartFile file : fileList) { logger.info("originalFileName : " + file.getOriginalFilename()); logger.info("size : " + file.getSize()); logger.info("contentType : " + file.getContentType()); byte[] fileData = file.getBytes(); String filePath = uploadPath; String fileName = file.getOriginalFilename(); File uploadFile = new File(filePath, fileName); FileCopyUtils.copy(fileData, uploadFile); // ํŒŒ์ผ ์—…๋กœ๋“œ } return "SUCCESS"; }
Java
๋ณต์‚ฌ