요청 데이터의 형식
복습!
http request 메시지의 데이터 형식은 3가지이다.
1. GET - 쿼리파라미터
2. POST (html form)
3. http message body
GET, POST
Get 방식과 html form의 Post는 둘 다 형식이 같으므로 구분 없이 조회 가능하다. 이것을 요청 파라미터 조회라고 한다. 이전에 알아봤던 방법은 HttpServletRequest 객체를 통해 조회하는 방법이다.
@RequestMapping("/request-param")
public void reqV1(HttpServletRequest request, HttpServletResponse response) {
String username = request.getParameter("username");
int age = Integer.parseInt(request.getParameter("age"));
log.info("{} {}", username, age);
}
스프링 MVC에서는 요청 파라미터를 바로 조회하는 방법이 있다.
@ResponseBody
@RequestMapping("/request-param-v2")
public String requestParam2(@RequestParam("username") String name,
@RequestParam("age") int age) {
log.info("{} {}", name, age);
return "ok";
}
@RequestParam이 결국 request.getParameter를 하는 것이다. PathVariable 때와 마찬가지로 변수명을 똑같이 맞춰주면 ("username"), ("age") 와 같은 괄호부분을 생략할 수 있다.
@ResponseBody
@RequestMapping("/request-param-v2")
public String requestParam2(String username, int age) {
log.info("{} {}", username, age);
return "ok";
}
추가로 @RequestParam 어노테이션 마저 없앨수도 있다. 변수명은 똑같이 맞춰줘야한다. 단 String, int, Integer 등의 단순 타입일 경우에만 가능하다.
생략가능하지만 넣는게 좋은 듯 하다. 넣게된다면
→ http 요청메시지의 파라미터로부터 가져오는 것인지 직관적으로 알 수 있다.
→ @RequestParam(required=false, defaultValue) 등의 기능을 사용할 수 있다.
(defaultValue = 기본값, required = 필수 파라미터인지 설정)
지금까지는 파라미터 하나하나를 조회하는 방법이었고 이제는 그 파라미터를 가지고 바로 객체로 만들어 조회하는 방법이다.
@ResponseBody
@RequestMapping("/model-v1")
public String model(@RequestParam(name="username", defaultValue="guest") String username,
@RequestParam(name="age", defaultValue="23") int age) {
HelloData obj = new HelloData();
obj.setUsername(username);
obj.setAge(age);
log.info("{}", obj);
return "good";
}
보통은 이런 방법으로 쿼리 파라미터를 받아 객체를 생성하지만 @ModelAttribute를 사용하면
@ResponseBody
@RequestMapping("/model-v1")
public String model(@ModelAttribute HelloData hello) {
log.info("{}", hello);
return "good";
}
🧐 ModelAttribute의 동작 순서
1. HelloData 객체 생성
2. 요청 파라미터의 이름으로 HelloData 객체의 프로퍼티 찾아서 setter 호출 (파라미터 이름이 username이면 setUsername 호출)
3. Model 에 addAttribute() 메소드를 호출하여 방금 생성한 객체를 넘겨줌. 이름 기본값은 클래스 첫글자를 소문자로 바꾼것.
프로퍼티 라는 것은 객체에 A 필드의 getter와 setter가 다 있으면 이 객체는 A 라는 프로퍼티를 가지고 있다 라고 한다.
모델 Attribute에서 중요한건 데이터 검증이다. 데이터 형식이 맞지 않으면 Exception이 발생하게 된다.
http message body
html의 form으로 post하는 것이나 get에서 쿼리 파라미터는 @RequestParam, @ModelAttribute로 받고 그 외에는 전부 HttpEntity를 사용하거나 데이터를 직접 꺼내야한다.
@PostMapping("/req-body-v3")
public HttpEntity<String> reqBodyV3(HttpEntity<String> httpEntity) throws IOException {
String body = httpEntity.getBody();
return new HttpEntity<>("message 직접 입력");
}
HttpEntity를 사용해서 데이터를 읽어들일 수 있다. HttpEntity는 헤더정보도 조회할 수 있다.
@ResponseBody
@PostMapping("/req-body-v5")
public String reqBodyV5(@RequestBody String message) throws IOException {
log.info(message);
return "ok";
}
body의 데이터를 가져올때 주로 가장많이 쓰이는 방법이다. 요청에 대해서는 RequestBody, 응답은 ResponseBody 를 통해 바디에 직접 메시지를 읽고 쓴다. 만약 요청 헤더에 형식이 application/json 이라면 메시지 컨버터가 객체로 변환해준다.
@ResponseBody
@PostMapping("/req-body-json1")
public String reqJson1(@RequestBody HelloData hello) {
System.out.println(hello.getAge(), hello.getUsername());
return "ok";
}
// httpEntity를 통해 객체로 바꿀수도 있다.
@ResponseBody
@PostMapping("/req-body-json3")
public String reqJson1(HttpEntity<HelloData> httpEntity) {
HelloData data = httpEntity.getBody();
return "ok";
}
메시지 컨버터가 바로 객체로 변환해서 파라미터로 전달해준다.
@RequestBody의 특징
생략이 불가능! → 생략하게 되면 ModelAttribute가 붙어서 메시지 바디가 아닌 쿼리 파라미터를 찾게됨
스프링 MVC 내부에서 Http 메시지 바디를 읽고 문자나 객체로 변환해서 전달해준다. 이때 HttpMessageConverter라는 기능을 사용한다.
마무리
요청 파라미터 조회 : @RequestParam, @ModelAttribute
Http 메시지 바디 : @RequestBody
관련글
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard
'백엔드 > 스프링' 카테고리의 다른 글
PRG (Post Redirect Get) (0) | 2021.08.19 |
---|---|
스프링 MVC - 응답데이터와 메시지 컨버터 (0) | 2021.08.19 |
스프링MVC 요청 매핑 (0) | 2021.08.18 |
스프링MVC의 Handler, View Resolver (0) | 2021.08.18 |
프론트 컨트롤러 패턴 (0) | 2021.08.17 |