- 웹에서 화면전환(새로고침) 없이 이루어지는 동작들은 대부분 비동기 통신으로 이루어진다.
- 비동기 통신을 하기 위해서는
- 클라이언트에서 서버로 요청 메시지를 보낼 때 본문(Body)에 데이터를 담아서 보내야 하고,
- 서버에서 클라이언트로 응답을 보낼 때 본문(Body)에 데이터를 담아서 보내야 한다.
- 즉, 요청본문 RequestBody, 응답본문 ResponseBody 를 담아서 보내야 한다.
이 때, Spring MVC의 @RequestBody 어노테이션과 @ResponseBody 어노테이션을 사용해 간편하게 데이터를 변환해서 송수신할 수 있다.
Post/PutMapping 요청핸들러 메소드의 파라미터에 부착하는 어노테이션
(GetMapping은 불가, 메시지바디에서 읽어올 게 없음)
주로 Ajax에 대한 요청을 보낼 때 사용된다. * post 해야 할 때
@RequestBody는 역직렬화 과정이 진행된다면,
@ResponseBody는 직렬화 과정이 진행된다.
@RequestBody | @ResponseBody |
---|---|
클라이언트 -> 서버 요청 | 서버 -> 클라이언트 응답 |
역직렬화 | 직렬화 |
(JSON 텍스트 -> 객체) | (객체 -> JSON 텍스트) |
* @ResponseBody 참고 링크
* 직렬화/역직렬화 참고 링크
@PostMapping("/product/modify")
@ResponseBody
public void modifyProduct(@RequestBody Product product) {
productService.updateProduct(product);
}
// 수정 폼 Ajax로 보내기
async function submitForm() {
// 1. 값 하나씩 읽어오기
// json으로 직렬화(전송에 용이한 형태로 변환)할 자바스크립트 객체 생성
let data = {
no: document.querySelector("input[name=no]").value,
category: {
no: document.querySelector("select[name=categoryNo]").value
},
description: document.querySelector("textarea[name=description]").value
};
// 2. 위의 data 객체를 직렬화(전송에 용이한 형태로 변환)
let jsonText = JSON.stringify(data);
// 3. POST 방식으로 JSON 데이터를 서버로 전송
let response = await fetch("/admin/product/modify", {
method: "POST",
headers: {
"Content-Type": "application/json", // json에 대한 컨텐츠 타입
"X-CSRF-TOKEN": document.querySelector("input[name='_csrf']").value
},
body: jsonText
});
// 이하 코드 생략...
}
(반환값의 타입)
을 탐색한다.* 클라이언트에서 서버로 응답 데이터 전송
(@ResponseBody가 아닐 때)
* 이 때는 View가 실행되지 않음
@GetMapping("/product/list")
public String list(@RequestParam("page") int page,
@RequestParam("opt") String opt,
@RequestParam("keyword") String keyword) {
}
* name=value&name=value&... 형태로 오는 것만
@RequestParam 없이 getParameter로 받을 수 있다.
@GetMapping("/product/list/{page}/{opt}/{keyword}")
public String list(@PathVariable("page") int page,
@PathVariable("opt") String opt,
@PathVariable("keyword") String keyword,) {
}
<form>
태그 작성<form method="post" action="add">
<input type="text" name="id">
<input type="password" name="password">
<input type="text" name="name">
<input type="text" name="email">
<button type="submit">등록</button>
</form>
@PostMapping("/add")
public String add(UserRegisterForm form) {
}
바디부에 들어있는 Content-Type은 컨텐츠 타입을 설명하는 값이고,
post 방식으로 전달할 때는 헤더부에 Content-Type이 꼭 있어야 한다.
* 해당 예시에서는 application/json, FormData에서는 enctype
값이 많을 때(배열)는 Pathvariable 불가
-> JSON이나 Form 이용
References