[Spring] @RequestParam, @RequestBody(& @ResponseBody), @ModelAttribute 차이
Spring에서 클라이언트로부터 받은 요청 정보를 받아오기 위해 사용하는 3가지 방법
@RequestParam, @RequestBody, @ModelAttribute
위 3가지 애너테이션은 클라이언트로 받는 요청 정보의 형태에 따라 어떤것을 사용할지가 다른 것으로
공통적으로 사용자로부터 받은 요청 정보를 가져올 수 있는 애너테이션을 의미한다.
요청의 형태가 어떤 경우에 각각을 사용하는지 알아보자!
@RequestParam이란?
: @RequestParam은 1개의 Http 요청 파라미터를 받기 위해 사용
: default로 required가 true이기 때문에 파라미터가 반드시 전송되어야 함
(만약, 반드시 필요한 값이 아니라면 required="false" 설정을, 기본값을 지정해주고자 한다면 defaultValue="기본값" 지정이 가능)
@RequestBody란?
: @RequestBody는 Json(application/Json) 형태의 Http body를 JAVA 객체로 변환하기 위해 사용
https://kcode-recording.tistory.com/74
- 우리는 클라이언트와 요청과 응답을 JSON 형태로 주고받는 경우가 많기에 JSON 직렬화/역직렬화를 해야 하는 경우가 많음
- ObjectMapper 클래스를 이용해 MappingJasckson2HttpMessageConverter를 통해 Java 객체로 변환
[JSON] JSON 직렬화/역직렬화
JSON 역직렬화(Deserialization) : 클라이언트 쪽에서 JSON 형식의 데이터를 서버 쪽으로 전송하면 서버 쪽의 웹 애플리케이션은 전달 받은 JSON 형식의 데이터를 DTO 같은 Java 객체로 변환하는 것을 의미
kcode-recording.tistory.com
* ObjectMapper는 Json을 Java로 변환하면서 객체의 기본 생성자를 통해 객체를 생성하고, Reflection을 사용하는데 이 때 setter 메서드가 반드시 필요한 것은 아니지만 변수의 이름을 찾기 위한 메서드들을 필요로 하기 때문에 getter 메서드를 구현하면 setter 없이도 바인딩이 가능함
@ResponseBody란?
: @ResponseBody는 JAVA 객체를 Json(application/Json) 형태로 변경하여 클라이언트에게 전송하기 위해 사용
- 위의 @RequestBody의 반대 개념이라고 생각해도 됨
@ModelAttribute란?
: @ModelAttribute는 form 형태의 Http body와 요청의 파라미터가 생성자가 setter로 바인딩하기 위해 사용
: @ModelAttribute를 이용해서 특정 파라미터의 값만 가져오는 것도 가능함
: Controller에서 view를 반환할 때 @ModelAttribute를 이용해서 가져온 객체를 그대로 반환하면 되는 경우에는 Model의 역할을 대신해줌 (단, 가져온 값이 아니라 추가적으로 뷰에 전달해야 하는 값이 있다면 Model을 사용해야 함)
* reflection을 사용해 필드를 인자로 받는 생성자가 있는지 검색하여, 생성자가 존재하면 생성자를 통해 값을 지정하고, 없다면 setter를 이용하는데 모든 필드나 일부 필드를 받을 경우 해당 생성자를 찾아 주입받고, 그것이 아니라면 setter를 이용해 값을 주입받음
코드를 통해 활용을 어떻게 해야 하는지 보고자 한다
[Member.java]
@Getter
@Setter
public class Member{
private String name;
private Integer age;
private String tel;
}
[MemberController.java]
@RestController
@RequestMapping("/member") // member 테이블과 매핑
public class MemberController{
@Autowired
private MemberService memberService;
@GetMapping("/requestParam")
public ResponseEntity requestParam(@RequestParam(value="name", requuired=false,
defaultValue="홍길동") String name){
// name 값이 없어도 되도록 설정한 후 기본 값을 지정함
return ResponseEntity.ok(memberService.getMember(name);
}
@PostMapping("/requestBody")
public ResponseEntity requestBody(@RequestBody Member member){
// Json 형태의 요청을 Java 객체로 변환
return ResponseEntity.ok(member);
}
@PostMapping("/modelAttribute")
public ResponseEntity modelAttribute(@ModelAttribute Member member){
// form 형태의 요청을 객체에 바인딩
return ResponseEntity.ok(member);
}
}
* 기본적으로 애너테이션의 경우에는 기능을 갖는 것이 아니라 각 애너테이션이 일 때 사용되는 구현체들이 존재하고 , Spring에서 ArgumentResolver 인터페이스를 통해 해당 애너테이션을 인지해 애너테이션에 맞는 처리 방식으로 동작하게 됨