@ResponseBody 작동 원리
@ResponseBody 어노테이션을 사용하지 않는 메서드와 @ResponseBody 어노테이션을 사용하는 두 개의 메서드를 비교하여 살펴본다.
@ResponseBody 어노테이션을 사용하여 페이지에 데이터만을 전달할 수 있다.
@RepsonseBody 사용 안 함
첫 번째로는 @RepsonseBody를 사용하지 않는 일반적인 메서드이다.
스프링 부트의 경우 웹 브라우저에서 (ex) localhost:8080/mvc를 통해 사이트에 접속하면 내장 톰캣 서버에서 mvc를 스프링에 넘겨주고, 스프링에서는 컨트롤러에 있는 Mapping을 따라 찾아간다. Mapping 된다면 ViewResolver로 토스되어(View를 통해서) 처리된다.
@GetMapping("mvc")
public String helloMvc(@RequestParam("name") String name, Model model) {
model.addAttribute("name", name);
return "hello-mvc";
}
GET 방식으로 데이터를 받고, Model을 사용해서 데이터를 넘겨주는 메서드이다.
데이터 전달은 Model을 사용한다. 따라서 페이지 소스 보기 시 <html> 태그 부분도 그대로 드러난다.
위 예시는 thymeleaf를 사용하였다.
@RepsonseBody 사용, 반환형이 String
두 번째는 @ResponseBody 어노테이션을 사용하고, 반환형이 문자열 타입인 경우이다.
첫 번째의 경우 URL에서 넘어온 값(mvc)과 컨트롤러에 있는 게 Mapping 되면 ViewResolver로 넘겨준다.
그러나 두 번째 경우는 @ResponseBody 어노테이션이 붙어 있기 때문에 ViewResolver로 넘기지 않고, 응답을 그대로 넘기는 것으로 동작한다. 응답을 그대로 넘길 때는 HttpMessageConverter가 동작한다. 아래 예제는 반환형이 String이므로 StringHttpMessageConverter가 동작한다.
본 경우는 실무에서는 거의 쓸 일이 없다.
@GetMapping("str")
@ResponseBody
public String helloStr(@RequestParam("name") String name) {
return "hello " + name;
}
@ResponseBody 어노테이션을 사용하고, 반환 값이 단순 문자열 값인 경우, 반환 값이 그대로 페이지에 출력된다.
첫 번째 코드와 달리 @ResponseBody를 사용하였기 때문에 페이지 소스 보기 시 <html> 태그가 존재하지 않는다. 정말 단순 반환된 문자열 값만 전달된 것이다. (꼭 반환 값이 문자열이 아니고, int형 숫자여도 해당 숫자만 출력된다.)
@RepsonseBody 사용, 반환형이 객체 타입
세 번째는 @ResponseBody 어노테이션을 사용하고, 반환형이 객체 타입인 경우이다.
두 번째 방식을 설명할 때 StringHttpMessageConverter가 동작한다고 하였는데, 아래 예제 방식에서는 MappingJackson2HttpMessageConverter가 동작하게 된다. MappingJackson2HttpMessageConverter가 동작하면 객체 값을 JSON 형태로 변경하여 웹 브라우저에 띄우게 된다.
해당 방식을 사용해 데이터 전달하는 것을 API 방식으로 데이터를 전달한다고 말한다.
@GetMapping("api")
@ResponseBody
public Hello helloApi(@RequestParam("name") String name) {
Obj obj = new obj();
obj.setName(name);
return obj;
}
static class Obj {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
편의상 Obj라는 static 클래스를 생성하였다. name 변수와 Getter, Setter가 존재한다.
helloApi 메서드에서는 Obj 타입 obj 인스턴스를 생성하고, GET 방식을 통해 받은 데이터(name)를 obj 객체의 name 변수에 저장한다. 이후 obj 객체를 반환한다.
두 번째 메서드와는 다르게 객체 값을 반환하였더니 데이터가 JSON 형태로 페이지에 출력된다.
현재는 보통 JSON 형태로 데이터를 많이 전달하기 때문에 세 번째 방법을 가장 많이 사용한다.