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
볡μ¬