스프링 웹 개발을 할 때에는 API의 방식을 활용하기도 한다. 사실 정적 컨텐츠(static content) 방식을 제외하면 MVC 방식에서 view를 찾아서 템플릿 엔진을 통해 화면을 렌더링해서 html을 웹 브라우저에 넘겨주는 방식이 있고, 그 다음에 API를 써서 html이 아니라 데이터를 바로 내리는 방식이 있다.
@ResponseBody를 사용
- HTTP의 BODY에 문자 내용을 직접 반환
- viewResolver 대신에 HttpMessageConverter가 동작
- 기본 문자처리: StringHttpMessageConverter
- 기본 객체처리: MappingJackson2HttpMessageConverter
- byte 처리 등등 기타 여러 HttpMessageConverter가 기본으로 등록되어 있음
참고: 클라이언트의 HTTP Accept 헤더와 서버의 컨트롤러 반환 타입 정보 둘을 조합해서 HttpMessageConverter가 선택된다.
@ResponseBody의 사용 원리는 다음과 같다. 웹 브라우저에서 localhost:8080/hello-api를 입력하면, 톰캣 내장 서버에서 "hello-api가 왔어" 하면서 스프링에 던진다. 그러면 스프링은 "hello-api가 있네. 그런데 @ResponseBody라는 어노테이션이 붙어있네" 한다. @ResponseBody가 붙어있지 않으면 스프링은 viewResolver에게 던진다. 그런데 @ResponseBody가 있으면 http 응답에 그대로 데이터를 넘긴다.
만약 문자인 경우에는, 그냥 문자 값을 http 응답에 바로 넣어서 준다.
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
public String helloString(@RequestParam("name") String name) {
return "hello " + name; // "hello spring"
}
}
이렇게 객체가 아니고 문자인 경우,
로 웹 브라우저에서 나타난다. 페이지 소스 보기를 했을 때에도,
이렇게 덩그러니 문자만 있는 것을 확인할 수 있다.
그런데 객체인 경우에는, 스프링 입장에서 그냥 json 방식으로 데이터를 만들어서 http 응답에 반환하는 것이 default 정책이다.
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;
}
}
}
@ResponseBody라고 오면, hello 객체를 넘긴다. 이 객체를 보고 몇 가지 조건을 본다. 우선, HttpMessageConverter가 동작을 한다. (기존에는 viewResolver가 동작했다.) 만약 단순 문자이면 StringConverter가 동작하고, 객체이면 JsonConverter가 동작한다. 그렇게 해서 이 hello 객체를 json 스타일로 바꾼다. "어, name이 있고 값이 있네" 하면서 json 스타일로 바꾼다. json으로 바꾼 것을 나를 요청한 웹 브라우저나 서버에 보내준다(응답을 한다).
이렇게 웹 브라우저에서 json 방식으로 나타난다.
(자바는 getter, setter를 사용한다. private이니 외부에서 바로 못 꺼낸다. 그래서 라이브러리에서 쓰거나, 이런 메소드를 통해서 접근을 한다. 이것을 '자바빈(JavaBean) 표준 규약'이라고 한다. '프로퍼티 접근 방식'이라고 부르기도 한다.)
기본 객체처리를 하는 MappingJackson2HttpMessageConverter은 객체를 json으로 바꿔주는 유명한 라이브러리 중 하나이다. 스프링은 Jackson 라이브러리를 기본으로 탑재하고 있다. http 스펙에 보면, 요청을 할 때 "나는 이런 포맷으로 받고 싶어"하는 것이 있다. 이것이 클라이언트의 HTTP Accept라는 헤더이다. 여기서 json이라고 요청이 오면 json으로 받고, 여기서 아무것도 안 보내면 다 받을 수 있다는 것으로 판단하고 스프링이 현재 보낼 수 있는 것으로 보낸다. 그런데 "나는 꼭 xml로 받을거야" 등 어떤 포맷으로 받을 것이라고 하면 이때 그 메세지 컨버터가 동작을 한다.
정리하자면, API 방식은 객체를 반환하는 것으로, HttpMessageConverter를 통해서 json 스타일로 바꿔서 반환을 해주는 것이다. view 같은 것은 없고 그대로 http response에 값을 넣어서 반환해준다.
'Framework > Spring' 카테고리의 다른 글
MVC와 템플릿 엔진 (0) | 2022.11.29 |
---|---|
정적 컨텐츠 (Static Content) (0) | 2022.11.29 |
스프링 부트 (Spring Boot) 동작 환경 (0) | 2022.11.28 |