html을 그대로 전달하는 정적 컨텐츠 방식을 제외하면
View를 찾아서 템플릿 엔진으로 화면 렌더링 후 html을 웹 브라우저에 넘겨주는 방식과
데이터를 바로 내려주는 API 방식이 있다.
HelloController
package hello.hellospring.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloController {
@GetMapping("hello-string")
@ResponseBody
// @ResponseBody : http body부에 데이터를 직접 넣어주겠다
public String helloString(@RequestParam("name") String name) {
return "hello " + name; // 리턴값을 그대로 내려줌
}
}
String 타입의 응답 데이터를 보내는 API 방식의 예이다.
이번에는 @ResponseBody 어노테이션을 사용했고, 리턴값으로 ViewName이 아닌 응답 데이터를 보내준다.

결과화면이다. 소스코드를 살펴보면 아무 html 코드 없이 데이터만 넘겨받은 것을 확인할 수 있다.
API 서비스를 위해 @ResponseBody 어노테이션을 사용한다.
템플릿 엔진을 사용한 예시에서는 attribute로 데이터를 넣고, 리턴값으로 ViewName을 넘겨주었다. 그러면 뷰 리졸버가 작동하여 해당 ViewName을 가진 html을 찾고, 템플릿 엔진이 Model의 attribute에 있는 데이터를 합성해 html을 만들어내는 방식이다.
참고:
https://velog.io/@namyj97/SPRING-MVC%EC%99%80-%ED%85%9C%ED%94%8C%EB%A6%BF-%EC%97%94%EC%A7%84
API 방식에서는 @ResponseBody 어노테이션을 사용하여 리턴값을 이용한 뷰 리졸버의 View 조회를 무시한다. 대신 리턴값을 이용해 http 메시지의 body부에 직접 넣어준다.
그 차이를 예시를 통해 살펴보자.
HelloController.java
@GetMapping("hello-mvc")
public String helloMvc(@RequestParam("name") String name, Model model) {
// attributeValue로 파라미터로 받은 name을 전달
model.addAttribute("name", name);
return "hello-template";
}
hello-template.html
<html xmlns:th="http://www.thymeleaf.org">
<body>
<p th:text="'hello ' + ${name}">hello! empty</p>
</body>
</html>

템플릿 엔진을 이용해 응답을 받은 예시 화면이다.
개발자도구를 통해 네트워크의 응답 부분을 살펴보면,
리턴값의 viewName에 해당하는 파일의 html 코드에 attribute로 넣어준 데이터가 합쳐져 완성된 html 코드 자체를 응답으로 받는 것을 확인할 수 있다.
HelloController.java
@GetMapping("hello-api")
@ResponseBody
public Hello helloApi(@RequestParam("name") String name) {
Hello hello = new Hello();
hello.setName(name);
return hello;
}

이번엔 API 방식이다.
개발자도구를 통해 네트워크의 응답 부분을 살펴보면, 리턴값으로 보내준 데이터를 그대로 응답으로 받아온 것을 확인할 수 있다.

@RequestParam("name") String name
http 요청 파라미터를 받을 때 파라미터와 사용할 변수를 매핑할 용도로 사용된다.
@RequestParam("파라미터 name") 변수타입 변수명
파라미터의 key값을 명시하여 변수와 바인딩할 수 있다.
API 방식으로 객체 데이터를 응답으로 보내는 예시를 살펴보자.
package hello.hellospring.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloController {
@GetMapping("hello-api")
@ResponseBody
public Hello helloApi(@RequestParam("name") String name) {
Hello hello = new Hello();
hello.setName(name);
return hello;
}
static class Hello {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
파라미터로 받아온 name을
만들어준 객체를 이용해 세팅 후 해당 객체를 리턴해준다.

화면에서는 json 형태로 데이터가 표시되는 것을 확인한다.
스프링에서는 객체 데이터를 응답으로 리턴하면 디폴트로 JSON 형태로 반환한다.
(객체 형식으로 응답을 리턴하면, JSON형식으로 데이터를 만들어 반환하겠다는 것이 기본 정책이다)
JSON 예시
{
"users": [
{
"name": 'HongGildong",
"age": 20
},
{
"name": 'KimJava",
"age": 30
}
]
}
JSON은 JavaScript Object Notation의 약어로 자바스크립트에서 객체에 대해 표현하는 포맷을 의미한다.
자바스크립트의 객체 표기법과 유사하게 {key: value}의 형태로 구성된다.
과거에는 태그를 사용하는 XML 방식도 많이 사용했으나, 시작태그<tagName>와 함께 종료태그</tagName>로 닫아줘야 한다는 점에서 무겁고 번거롭다는 단점이 있다. 최근에는 거의 JSON 방식의 데이터 포맷을 사용한다.
객체를 JSON 형식으로 바꿔주는 대표적인 라이브러리로 Jackson, 구글의 Gson이 있다.
스프링은 Jackson을 선택하여 기본으로 탑재하고 있다. 스프링에서 객체를 JSON 형식으로 변환할 때 MappingJackson2HttpMessageConverter를 사용한다.
그러면 @ResponseBody 어노테이션을 사용할 경우, url 요청을 받아 데이터를 응답하기 까지의 원리를 살펴보자.

@ResponseBody를 사용하면
http의 body에 문자 내용을 직접 반환한다.