Search

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 μ‚¬μš©

β€’
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
볡사
ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ 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 */ @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>Insert title here</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("/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

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("/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("/data/board/list") @RequestMapping(value = "/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 = "/data/map") @RequestMapping(value = "/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("제λͺ©1","μž‘μ„±μž1","λ‚΄μš©1")); map.put("board2", new Board("제λͺ©2","μž‘μ„±μž2","λ‚΄μš©2")); map.put("board3", new Board("제λͺ©3","μž‘μ„±μž3","λ‚΄μš©3")); return map; }
Java
볡사

ResponseEntity

ResponseEntity<Void>

@ResponseBody @RequestMapping("/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("/data/entity/string") public ResponseEntity<String> responseEntityString() { // new ResponseEntity<λ°˜ν™˜νƒ€μž…>(μ‘λ‹΅λ©”μ‹œμ§€, μƒνƒœμ½”λ“œ); return new ResponseEntity<String>("SUCCESS", HttpStatus.OK); }
Java
볡사

ResponseEntity<Board>

@ResponseBody @RequestMapping("/data/entity/board") public ResponseEntity<Board> responseEntityBoard() { Board board = new Board("제λͺ©","μž‘μ„±μž","λ‚΄μš©"); return new ResponseEntity<Board>(board, HttpStatus.OK); }
Java
볡사

ResponseEntity<List<Board>>

@ResponseBody @RequestMapping("/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("/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("/data/file") public ResponseEntity<byte[]> responseFile(HttpServletRequest request) throws Exception { String path = request.getServletContext().getRealPath("/WEB-INF/upload/test.png"); logger.info("path : " + path); // 파일 경둜 // String filePath = "E:\\TJE\\UPLOAD\\test.jpg"; String filePath = request.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 파일 μ—…λ‘œλ“œ

파일 μ—…λ‘œλ“œ

β€’
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
볡사