๐ฏ ๋ชฉํ : Spring MVC์์์ HTTP ์์ฒญ / ์๋ต ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๋ ๋ฐฉ๋ฒ์ ๋ํ ํ์ต๋ด์ฉ ์ ๋ฆฌ
# GET ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ ์ ์ก
http://localhost:8080/request-param?username=lee&age=20
# POST HTML Form ํ์์ผ๋ก ์ ์ก
POST /request-param ...
content-type: application/x-www-form-urlencoded
username=lee&age=20
// ๋์ผํ ๋งตํ์ผ๋ก log๋ฅผ ํ์ธํ๊ธฐ ์ํด์๋ ํ๋์ฉ ์ฃผ์ ์ฒ๋ฆฌํ๊ณ ํด์ผํ๋ค.
@Slf4j
@Controller
public class RequestParamController {
@RquestMapping("/request-param")
public void requestParamServlet(HttpServletRequest request, HttpServletResponse response) throws IOException {
String username = request.getParameter("username");
int age = Integer.parseInt(request.getParameter("age"));
log.info("username={}, age={}", username, age);
response.getWriter().write("ok");
}
@ResponseBody /* View ์กฐํ๋ฅผ ๋ฌด์ํ๊ณ HTTP message Body์ String ๋ฐ์ดํฐ๋ฅผ ์ง์ ์ ์กํ๋ค */
@RequestMapping("/request-param")
public String requestParamAnnotation(
@RequestParam String username,
@RequestParam int age
) {
log.info("username={}, age={}", username, age);
return "ok";
}
@ResponseBody
@RequestMapping("/request-param")
public String requestParamBasic(String username, int age) {
log.info("username={}, age={}", username, age);
return "ok";
}
@ResponseBody
@RequestMapping("/request-param")
public String requestParamMap(@RequestParam Map<String, Object> paramMap) {
log.info("username={}, age={}",
paramMap.get("username"),
paramMap.get("age"));
return "ok";
}
@ResponseBody
@RequestMapping("/request-param")
private String modelAttributeV1(@ModelAttribute HelloData helloData) {
/* HelloData ๋ชจ๋ธ ๊ฐ์ฒด๊ฐ ์์ฑ๋๊ณ ํ๋ผ๋ฏธํฐ์ ๊ฐ์ ๋ฐ์ธ๋ฉํด์ค๋ค.*/
log.info("HelloData = {}",helloData);
return "ok";
}
@ResponseBody
@RequestMapping("/request-param")
private String modelAttributeV2(HelloData helloData) {
/* HelloData ๋ชจ๋ธ ๊ฐ์ฒด๊ฐ ์์ฑ๋๊ณ ํ๋ผ๋ฏธํฐ์ ๊ฐ์ ๋ฐ์ธ๋ฉํด์ค๋ค.*/
log.info("HelloData = {}",helloData);
return "ok";
}
}
request.getParameter
๋ ๋จ์ํ HttpServletRequest๊ฐ ์ ๊ณตํ๋ ๋ฐฉ์์ผ๋ก ์์ฒญ ํ๋ผ๋ฏธํฐ๋ฅผ ์กฐํํ ์ ์๋ค.@RequestParam
์ด๋
ธํ
์ด์
์ ์์ฒญ ํ๋ผ๋ฏธํฐ๋ฅผ ํธ๋ฆฌํ๊ฒ ์กฐํ ํ ์ ์๊ฒ ํ๋ค.@RequestParam("username") String memberName
๊ณผ ๊ฐ์ด key ๊ฐ์ ์ง์ ํด์ฃผ๋ฉด ๋งค๊ฐ ๋ณ์์ ๋ค์ด๋ฐ์ ์ง์ ์ง์ ํ ์ ์๋ค.@RequestParam(required = true, defaultValue = "guest") String username
@RequestParam(required = true, defaultValue = "-1") int age
@RequestParam
์ ์๋ตํ๊ณ key ๊ฐ๊ณผ ๊ฐ์ ๋งค๊ฐ ๋ณ์๋ช
์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ์ ์๋ค.@RequestParam
์ด๋
ธํ
์ด์
์ Map ํ์์ผ๋ก๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ ์๋ค.@ModelAttribute
์ด๋
ธํ
์ด์
์ ๊ฐ์ฒด์ ํ๋ผ๋ฏธํฐ ๊ฐ์ ๋ฐ์ธ๋ฉ ํด์ค๋ค.HelloData
ํด๋์ค๋ username๊ณผ age๋ฅผ ํ๋ ๋งด๋ฒ๋ก ๊ฐ์ง๊ณ ์๋ค๊ณ ๊ฐ์ ํ๊ณ setter, getter์ ํ์ํ ์์ฑ์๊ฐ ์๋ค๊ณ ๊ฐ์ ํ๋ค.@ModelAttribute
๋ ์๋ต ๊ฐ๋ฅํ๋ค. ์์ฒญ ํ๋ผ๋ฏธํฐ์ ๋งค์นญ๋๋ ํ๋ ๋งด๋ฒ๊ฐ ์๋ค๋ฉด ์๋์ผ๋ก ๋ฐ์ธ๋ฉ ํด์ค๋ค.HelloData
๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค.HelloData
๊ฐ์ฒด์ ํ๋กํผํฐ๋ฅผ ์ฐพ๊ณ ํด๋น ํ๋กํผํฐ์ setter๋ฅผ ํธ์ถํด์ ํ๋ผ๋ฏธํฐ์ ๊ฐ์ ๋ฐ์ธ๋ฉ ํ๋ค.@ModelAttribute
๊ณผ @RequestParam
๋๋ค ์๋ต ๊ฐ๋ฅํ๋ค. ์ด๋ค ๊ธฐ๋ฅ์ด ์ฐ์ ์์๊ฐ ๋ ๊น?@RequestParam
์ด ์ฐ์ ์ผ๋ก ์ ์ฉ๋๋ค.@ModelAttribute
๊ฐ ์ ์ฉ๋๋ค.@RequestParam
๊ณผ @ModelAttribute
๋ฅผ ์ฌ์ฉํ ์ ์๋ค.(HTML Form ํ์์ผ๋ก ์ ๋ฌ๋๋ ๊ฒฝ์ฐ ์ ์ธ)raw, JSON, content-type: application/json
{"username":"Lee", "age":20}
์ ๊ฐ์ด JSON ํ์
์ ๋ฐ์ดํฐ๊ฐ ์์ฒญ ๋ฉ์ธ์ง๋ก ๋ค์ด ์จ๋ค๊ณ ๊ฐ์ ํ๋ค@Controller
@Slf4j
public class RequestBodyJsonController {
private ObjectMapper objectMapper = new ObjectMapper();
@PostMapping("/request-body-json-v1")
public void requestBodyJsonV1(HttpServletRequest request, HttpServletResponse response) throws IOException {
ServletInputStream inputStream = request.getInputStream();
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
log.info("messageBody = {}", messageBody);
HelloData data = objectMapper.readValue(messageBody, HelloData.class);
log.info("username={}, age={}", data.getUsername(), data.getAge());
response.getWriter().write("ok");
}
@ResponseBody
@PostMapping("/request-body-json-v2")
public String requestBodyJsonV2(@RequestBody String messageBody) throws IOException {
log.info("messageBody = {}", messageBody);
HelloData data = objectMapper.readValue(messageBody, HelloData.class);
log.info("username={}, age={}", data.getUsername(), data.getAge());
return "ok";
}
@ResponseBody
@PostMapping("/request-body-json-v3")
public String requestBodyJsonV3(@RequestBody HelloData helloData) {
log.info("username={}, age={}", helloData.getUsername(), helloData.getAge());
return "ok";
}
@ResponseBody
@PostMapping("/request-body-json-v4")
public String requestBodyJsonV4(HttpEntity<HelloData> data) {
HelloData helloData = data.getBody();
log.info("username={}, age={}", helloData.getUsername(), helloData.getAge());
return "ok";
}
}
InputStream
, OutputStream
์ ํ์ฉํ์ฌ Stringํ์
์ ๋จ์ ๋ฉ์ธ์ง ๋ฐ๋์ ๋ด์ฉ์ ์กฐํํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅ ํ ์๋ ์์ผ๋ฉฐ HttpServletRequest request
, HttpServletResponse response
๋ฅผ ํ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ObjectMapper
๋ก ๋งตํํ์ฌ JSON ํ์
์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฒด์ ์ ์ฉ ํ ์ ์๋ค.@RequestBody
๋ฅผ ์ฌ์ฉํ์ฌ HTTP ๋ฉ์ธ์ง์์ ๋ฐ์ดํฐ๋ฅผ ๊บผ๋ด๊ณ ObjectMapper
๋ฅผ ์ฌ์ฉํ์ฌ ์๋ฐ ๊ฐ์ฒด๋ก ๋งตํ ํ๋ค.@RequestBody
๋ฅผ ์ฌ์ฉํ์ฌ ์ง์ ๊ฐ์ฒด์ ๋งค๊ฐ ๋ณ์๋ก ์ง์ ํ๋ฉด, ๋ณ๋์ ๋งตํ์ด ํ์ ์์ด ๋ฐ์ดํฐ๋ฅผ ๋ด์์ ์๋ค.(HelloData
)HttpEntity
๋ฅผ ํ์ฉํ์ฌ HTTP Header,Body๋ฅผ ์กฐํํ ์ ์๋ค.HttpEntity
๋ฅผ ์์ ๋ฐ์ RequestEntity
์ ResponseEntity
๋ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.HttpEntity
์ @RequestBody
๋ HTTP ๋ฉ์ธ์ง ์ปจ๋ฒํฐ๊ฐ HTTP ๋ฉ์ธ์ง ๋ฐ๋์ ๋ด์ฉ์ ์ํ๋ ๋ฌธ์๋ ๊ฐ์ฒด๋ก ๋ณํ ํด ์ค๋ค. ๋ฌธ์ ๋ฟ๋ง ์๋๋ผ JSON ํ์
์ ๊ฐ์ฒด๋ก ๋ณํ๋ ์ง์ํ๋ค.@Slf4j
@Controller
public class ResponseBodyController {
@GetMapping("/response-body-string-v1")
public void responseBodyV1(HttpServletResponse response) throws IOException {
response.getWriter().write("ok");
}
@GetMapping("/response-body-string-v2")
public ResponseEntity<String> responseBodyV2() {
return new ResponseEntity<>("ok", HttpStatus.OK);
}
@ResponseBody
@GetMapping("/response-body-string-v3")
public String responseBodyV3() {
return "ok";
}
@GetMapping("/response-body-json-v1")
public ResponseEntity<HelloData> responseBodyJsonV1() {
HelloData helloData = new HelloData();
helloData.setUsername("userA");
helloData.setAge(20);
return new ResponseEntity<>(helloData, HttpStatus.OK);
}
@ResponseStatus(HttpStatus.OK)
@ResponseBody
@GetMapping("/response-body-json-v2")
public HelloData responseBodyJsonV2() {
HelloData helloData = new HelloData();
helloData.setUsername("userA");
helloData.setAge(20);
return helloData;
}
}
HttpServletResponse
๊ฐ์ฒด๋ฅผ ํตํด HTTP ๋ฉ์ธ์ง ๋ฐ๋์ ์ง์ ์๋ต ๋ฉ์ธ์ง๋ฅผ ์ ๋ฌ ํ ์ ์๋ค.ResponseEntity
๋ HttpEntity
๋ฅผ ์์ ๋ฐ์ HTTP ๋ฉ์ธ์ง์ ํค๋์ ๋ฐ๋ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ, HTTP ์๋ต ์ฝ๋๋ฅผ ์ค์ ํ์ฌ ๋ฐํ ํ ์ ์๋ค.@ResponseBody
๋ฅผ ์ฌ์ฉํ๋ฉด HTTP ๋ฉ์ธ์ง ์ปด๋ฒํฐ๋ฅผ ํตํด HTTP ๋ฉ์ธ์ง๋ฅผ ์ง์ ์
๋ ฅ ํ ์ ์์ผ๋ฉฐ, ResponseEntity
์ ๋์ผํ ๋ฐฉ์์ผ๋ก ๋์ ํ๋ค.ResponseBody
์๋ ์๋ต ์ฝ๋๋ฅผ ์ฌ์ฉ ํ ์ ์๋๋ฐ @ResponseStatus(HttpStatus.OK)
์ ๊ฐ์ ์ด๋
ธํ
์ด์
์ ์ด์ฉํ์ฌ ์๋ต ์ฝ๋๋ฅผ ์ค์ ํ ์ ์๋ค.ResponseEntity
๋ฅผ ๋ฐํํ๊ฒ ๋๋ฉด HTTP ๋ฉ์ธ์ง ์ปจ๋ฒํฐ๋ฅผ ํตํ์ฌ JSON ํ์์ผ๋ก ๋ณํ๋์ด ๋ฐํํ๋ค.@RequestBody
, HttpEntity
ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉํ๋ค.canRead
๋ฉ์๋๋ฅผ ํธ์ถํ๋ค.text/plain
, application/json
, */*
canRead
๋ฉ์๋์ ์กฐ๊ฑด์ ๋ง์กฑํ๋ฉด read()
๋ฅผ ํธ์ถํด์ ๊ฐ์ฒด ์์ฑํ๊ณ , ๋ฐํํ๋ค.@ResponseBody
, HttpEntity
๋ก ๊ฐ์ด ๋ฐํ๋๋ค.canWrite
๋ฉ์๋๋ฅผ ํธ์ถํ๋ค.text/plain
, application/json
, */*
canWrite
๋ฉ์๋ ์กฐ๊ฑด์ ๋ง์กฑํ๋ฉด write()
๋ฅผ ํธ์ถํด์ HTTP ์๋ต ๋ฉ์์ง ๋ฐ๋์ ๋ฐ์ดํฐ๋ฅผ ์์ฑํ๋ค.