스프링 프레임워크의 JSON 데이터 교환 이해하기

김동헌·2024년 3월 19일
0

SpringBoot

목록 보기
15/19
post-thumbnail

웹 애플리케이션에서의 데이터 교환은 클라이언트와 서버 간의 상호작용을 통해 이루어집니다.

이 과정은 HTTP(Hypertext Transfer Protocol)를 사용하여 실행되며, HTTP는 인터넷에서 데이터를 교환하는 데 사용되는 주요 프로토콜입니다.

클라이언트가 웹 페이지를 요청하거나 서버에 정보를 제출할 때, 서버가 이러한 요청에 응답할 때 모두 HTTP 요청과 응답 메시지를 통해 이루어집니다.

메시지들은 구조적으로 헤더와 바디, 두 주요 부분으로 나뉘어 있으며, 이 구조를 통해 다양한 유형의 정보와 데이터가 효율적으로 전송됩니다.

HTTP 메시지의 바디는 데이터 전송에 사용되며, 특히 JSON 형식으로 데이터를 손실 없이 효율적으로 주고받는 데 자주 사용됩니다.

스프링 프레임워크는 이 과정을 간소화하기 위해 @RequestBody@ResponseBody 애너테이션을 제공합니다.

  • @RequestBody 애너테이션은 클라이언트로부터 받은 HTTP 요청 바디를 자바 객체로 변환할 때 사용되며,

  • @ResponseBody 애너테이션은 서버가 클라이언트로 데이터를 반환할 때, 메소드의 반환 값을 HTTP 응답 바디로 직접 매핑하여 JSON 형태로 클라이언트에 전송하도록 합니다.

이러한 애너테이션을 활용해 개발자는 HTTP 통신 과정에서 복잡한 데이터 바인딩과 변환 작업 없이, 데이터를 쉽고 효율적으로 주고받을 수 있습니다.


@RequestBody 역할

서버가 @RequestBody 애너테이션을 사용하여 컨트롤러 메소드의 파라미터로 설정해 클라이언트에게 데이터 요청 형식을 지정

HTTP 요청 본문의 내용을 자바 객체로 역직렬화

  • 클라이언트로부터 받은 HTTP 요청 본문의 데이터(예: JSON, XML)를 서버 측의 자바 객체로 변환(역직렬화)합니다.

서버 측 객체에 매핑

  • 변환된 자바 객체는 컨트롤러 메소드의 파라미터로 전달되어,
    요청 처리 로직에서 사용될 수 있습니다.

데이터 타입의 일치 필요성

  • @RequestBody 애너테이션으로 선언된 파라미터의 타입이 클라이언트에서 전송된 데이터의 형식과 일치해야 합니다.

@ResponseBody 역할

서버의 객체를 HTTP 응답 본문으로 직렬화

  • 서버에서 클라이언트로 데이터를 반환할 때, 해당 메소드의 반환 객체를 HTTP 응답 본문의 형태로 변환(직렬화)합니다.

HTTP 응답 본문에 매핑

  • 직렬화된 데이터는 HTTP 응답 본문으로 클라이언트에게 전송됩니다.

다양한 응답 형식 지원

  • JSON, XML 등 클라이언트가 요구하는 다양한 형식의 응답을 생성할 수 있습니다.

View Reslove 대신 HttpMessageConverter이 동작

  • @ResponseBody 애너테이션이 없다면 메소드의 반환 값을 View 이름으로 간주하고, 스프링은 반환 값에 해당하는 View를 찾아 렌더링 과정을 거치게 됩니다.
  • @ResponseBody 애너테이션이 있다면 메소드의 반환 값을 HTTP 응답으로 처리합니다.

동작 방식

@ResponseBody 애너테이션은 컨트롤러 메소드에서 반환하는 문자열이나 객체를 HTTP 응답 본문에 직접 매핑하기 위해 사용

스프링의 @ResponseBody은 기본적으로 JSON으로 반환하도록 되어있다.(HTML로 변경 가능)

서버에서 데이터를 반환할 때 @ResponseBody 애너테이션을 사용해 반환할 경우 데이터 타입에 따라 적절한 HttpMessageConverter를 선택하여 반환하게 됩니다.

  • 문자 반환 시 : 반환되는 객체가 문자열(String) 타입이라면 StringHttpMessageConverter가 동작하여 해당 문자열을 HTTP 응답 본문으로 변환하고 반환합니다. 클라이언트는 단순 텍스트 형태의 응답을 반환받게 됩니다.

  • 객체 반환 시 : 반환되는 객체가 자바 객체라면 MappingJackson2HttpMessageConverter가 동작하여 객체를 JSON형태로 변환한 뒤, 그 결과를 HTTP 응답 본문으로 반환합니다.
    이 방법은 RESTful API에서 클라이언트와 서버 간에 데이터를 교환하는 표준적인 방법입니다.

@Response 애너테이션을 사용해 개발자는 복잡한 변환 로직을 직접 구현하지 않고도 다양한 형태의 응답을 쉽게 생성할 수 있습니다.


MappingJackson2HttpMessageConverter

객체를 JSON으로 바꿔주는 라이브러리는 다양하고, 대표적으로 크게 FasterXML의 Jackson구글의 Gson이 있습니다.

Jackson은 스프링 부트의 기본 JSON 처리 라이브러리spring-boot-starter-web에 포함된 fasterxml.jackson 라이브러리는 JSON 데이터의 직렬화 및 역직렬화를 처리하는 데 사용됩니다.

  • 개발자는 다양한 라이브러리로 변경이 가능합니다.
    (내장 서버인 톰캣을 아파치 등,, 으로 변경하는 것처럼 !)

그러면 확인해볼까요 ?

implementation 'org.springframework.boot:spring-boot-starter-web'을 기본적으로 build.gradle에 추가하게 되면
사진처럼 starter-web:3.2.0json 의존 관계 라이브러리 를 살펴보면 fasterxml.jackson이 기본적으로 포함되어 있는 것을 보실 수 있습니다.


@RestController

그런데 말이죠,, 저는 @ResponseBody 애너테이션을 사용해본 기억이 없었습니다.

클라이언트에게 데이터를 요청받을 때 @RequestBody를 사용해본 경험이 있지만 @ResponseBody는 사용해보지 않았더라구요.

그래서 다양한 자료들을 보면서 참고해보니 @ControllerRestController의 차이였습니다 !

간단하게 코드로 살펴보고 마무리 하겠습니다 !

@RequestMapping("/study")
@ResponseBody 
public HashMap<String, String> study() {
	HashMap<String, String> map = new HashMap<String, String>();
	map.put("userid", "Heon");
	map.put("purpose", "Happy");
	return map;
}

위 코드에서 만약 @ResponseBody 애너테이션이 빠지면 어떻게 될까요 ?

  • Spirng MVC에서 해당 메소드의 반환 값을 HTTP 응답 본문으로 직접 매핑하지 않게 됩니다. 대신에 반환 값을 View 이름으로 해석되고, 해당 View를 찾고 View를 렌더링하는 과정을 거치게 됩니다.
  • 기본적으로 @ResponseBody 애너테이션을 사용하면 View Reslove를 거치지 않고 데이터를 반환하지만 이 애너테이션이 빠진다면 반환 값에 매칭되는 View를 찾게 되는거죠.
    • 이 과정에서 적절한 View를 찾지 못하면 오류가 발생하게 됩니다.

그런데 @ResponseBody 애너테이션이 없어도 되는 경우가 있습니다.

저의 경우 이 경우에 해당되어 해당 애너테이션을 사용해 본 경험이 없던 것이죠 !

@Controller 애너테이션이 클래스 레벨에 설정되어 데이터를 반환 할 예정이라면 반드시 @ResponseBody가 필요합니다.

그런데 @RestController 애너테이션이 컨트롤러의 클래스 레벨에 설정되어 있다면 @ResponseBody가 필요 없게 되죠 !

@RestController@Controller@ResponseBody를 결합한 것으로, 클래스 레벨에서 @ResponseBody를 암시적으로 적용하여 모든 메소드의 반환 값이 기본적으로 HTTP 응답 본문으로 매핑되게 됩니다.

저는 항상 @Controller 애너테이션을 사용하지 않고
@RestController 애너테이션을 사용해 @ResponseBody가 자동적으로 적용이 되었던거였네요 !


정리

  • @RequestBody은 컨트롤러 메소드의 파라미터에 사용되며, 클라이언트로부터 받은 HTTP 요청 본문을 해당 파라미터의 타입으로 역직렬화한다.
    • 이때, @RequestBody 애너테이션으로 선언된 파라미터의 타입이 클라이언트에서 전송된 데이터의 형식과 일치해야한다.

  • @ResponseBody 는 컨트롤러 메소드에 사용되며, 메소드가 반환하는 객체를 HTTP 응답 본문으로 직렬화하여 클라이언트에게 반환한다.
    • 이 과정에서 View Resolver를 거치지 않고, 대신에 HttpMessageConverter를 사용하여 객체를 JSON, XML 등의 형태로 변환한다.

  • @RestController 는 클래스 레벨에서 사용되며, @Controller@ResponseBody의 기능이 합쳐져있다.

    • @RestController가 적용된 컨트롤러에서는 모든 메소드의 반환 값이 자동으로 HTTP 응답 본문으로 매핑됩니다.

      • 즉, 각 메소드에 별도로 @ResponseBody를 선언할 필요가 없다.
profile
백엔드 기록 공간😁

1개의 댓글

comment-user-thumbnail
2024년 3월 30일

잘 읽고 갑니다 !

답글 달기