스프링 프레임워크를 사용하여 개발을 하다 보면 request
→ POJO 객체 (JAVA로 생성하는 순수한 객체) → response
로 데이터가 흘러가게 된다. 들어오고 나가는 데이터를 JSON 포맷으로 처리하는 경우가 많은데 이를 어떻게 처리하는 지에 대해서 알아보고자 한다.
스프링 부트 프로젝트에서 JSON 데이터를 다룰 때 가장 많이 사용하는 것은 Jackson 라이브러리이다.
Jackson 라이브러리는 spring-boot-starter-web
에 Jackson
라이브러리를 제공하고 있기 때문에 JSON의 직렬/역직렬화에는 Jackson을 주로 사용한다.
JSON 뿐만 아니라 XML,YAML, CSV 등 다양한 형식의 데이터를 지원하는 data-processing 툴이다.
특히나 @RestController
를 사용하는 경우 요청과 응답의 객체 변환, 직렬화/역직렬화를 자동으로 Jackson 라이브러리가 담당하게 된다.
객체를 바이트 스트림으로 변환하는 과정
쉽게 말하면 자바 객체를 JSON 문자열로 변환하는 것
직렬화된 바이트 스트림을 원래의 객체로 복원하는 과정
JSON 문자열을 자바 객체로 변환하는 것
@RestController
와 @RequestBody
, @ResponseBody
를 사용하기스프링 부트는 내부적으로 Jackson 라이브러리를 사용하여 JSON 처리를 자동으로 수행한다. @RestController
와 @RequestBody
, @ResponseBody
어노테이션을 사용하면 JSON 직렬화 및 역직렬화를 자동으로 처리해준다.
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api")
public class MyController {
@PostMapping("/json")
public MyObject receiveJson(@RequestBody MyObject myObject) {
// JSON 데이터를 Java 객체로 자동 변환
return myObject; // Java 객체를 JSON으로 자동 변환하여 응답
}
}
@RequestBody
에서 요청의 JSON 데이터를 MyObject 객체로 변환하고, @ResponseBody
는 MyObject 객체를 JSON 형식으로 변환하여 응답한다.
@JsonProperty
와 기타 Jackson 어노테이션 사용하기import com.fasterxml.jackson.annotation.JsonProperty;
public class MyObject {
@JsonProperty("name")
private String name;
@JsonProperty("age")
private int age;
// getters and setters
}
Jackson의 다양한 어노테이션을 사용하여 JSON 직렬화/역직렬화 동작을 제어할 수 있다.
특정한 요구사항이 있을 때는 ObjectMapper를 직접 사용할 수 있다.
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonExample {
public static void main(String[] args) {
ObjectMapper objectMapper = new ObjectMapper();
MyObject myObject = new MyObject();
myObject.setName("John");
myObject.setAge(30);
try {
// 객체를 JSON 문자열로 변환
String jsonString = objectMapper.writeValueAsString(myObject);
System.out.println(jsonString);
// JSON 문자열을 객체로 변환
MyObject deserializedObject = objectMapper.readValue(jsonString, MyObject.class);
System.out.println(deserializedObject.getName());
} catch (Exception e) {
e.printStackTrace();
}
}
}
class MyObject {
private String name;
private int value;
// 생성자, getter, setter 생략
}
편의성, 유연성, 통합성
클래스 | 메서드 | 설명 |
---|---|---|
ObjectMapper | writeValueAsString(value: Any) | 지정된 객체를 JSON 문자열로 직렬화합니다. |
ObjectMapper | readValue(content: String, valueType: TypeReference) | 주어진 JSON 문자열을 지정된 타입의 객체로 변환합니다. |
ObjectMapper | configure() | ObjectMapper의 구성을 설정합니다. |
ObjectMapper | registerModule(module: Module) | 지정된 모듈을 |
ObjectMapper | disable(feature: JsonParser.Feature) | 지정된 JSON 파서 기능을 비활성화합니다. |
ObjectMapper | enable(feature: JsonParser.Feature) | 지정된 JSON 파서 기능을 활성화합니다. |
ObjectMapper | findAndRegisterModules() | 클래스 경로에서 사용 가능한 모듈을 찾아 ObjectMapper에 등록합니다. |
ObjectMapper | writerWithDefaultPrettyPrinter() | 기본 PrettyPrinter를 사용하는 ObjectWriter를 반환합니다. |
ObjectMapper | setVisibilityChecker(checker: VisibilityChecker<*>) | 지정된 가시성 검사기를 ObjectMapper에 설정합니다. |
ObjectMapper | setDefaultPropertyInclusion(inclusion: JsonInclude.Include) | 기본 속성 포함 규칙을 설정합니다. |
ObjectMapper | setSerializationInclusion(inclusion: JsonInclude.Include) | 직렬화 중에 속성을 포함할지 여부를 설정합니다. |
ObjectMapper | setDeserializationInclusion(inclusion: JsonInclude.Include) | 역직렬화 중에 속성을 포함할지 여부를 설정합니다. |
ObjectMapper | configure(feature: SerializationFeature, state: Boolean) | 지정된 직렬화 기능을 설정하거나 해제합니다. |
ObjectMapper | configure(feature: DeserializationFeature, state: Boolean) | 지정된 역직렬화 기능을 설정하거나 해제합니다. |
ObjectMapper | configure(feature: MapperFeature, state: Boolean) | 지정된 매퍼 기능을 설정하거나 해제합니다. |
ObjectMapper | configure(feature: JsonParser.Feature, state: Boolean) | 지정된 JSON 파서 기능을 설정하거나 해제합니다. |
ObjectMapper | configure(feature: JsonGenerator.Feature, state: Boolean) | 지정된 JSON 생성기 기능을 설정하거나 해제합니다. |
ObjectMapper | enableDefaultTyping() | 기본 타입 정보 포함을 활성화합니다. |
ObjectMapper | disableDefaultTyping() | 기본 타입 정보 포함을 비활성화합니다. |
readValue(...)
를 사용하고writeValue(...)
를 사용한다. 스프링부트는 HttpMessageConverters를 통해 JSON 데이터를 변환한다. 기본적으로는 Jackson이 사용되지만 Gson 등 다른 라이브러리를 사용할 수도 있다.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
@Configuration
public class AppConfig {
@Bean
public GsonHttpMessageConverter gsonHttpMessageConverter() {
return new GsonHttpMessageConverter();
}
}
참고문헌
https://mangkyu.tistory.com/223
https://velog.io/@jmjmjmz732002/Springboot-Open-API%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-Spring-%EC%84%9C%EB%B2%84-%EA%B0%9C%EB%B0%9C%ED%95%98%EA%B8%B0#json-deserialize
https://adjh54.tistory.com/375
https://beaniejoy.tistory.com/75
https://blog.naver.com/PostView.naver?blogId=doctor-kick&logNo=222311414600&redirect=Dlog&widgetTypeCall=true&directAccess=false
https://theheydaze.tistory.com/247
https://adjh54.tistory.com/379
https://www.javadoc.io/doc/com.fasterxml.jackson.core/jackson-databind/latest/index.html
https://sabarada.tistory.com/236#google_vignette
https://velog.io/@kny8092/ObjectMapper-%EC%A7%9A%EA%B3%A0-%EB%84%98%EC%96%B4%EA%B0%80%EA%B8%B0#%EC%95%8C%EA%B3%A0-%EC%9E%88%EB%8D%98-%EA%B2%83