JSON(JavaScript Object Notation)은 애플리케이션에서 쉽게 구문 분석 및 생성할 수 있는 키-값 쌍의 모음입니다. 이는 JavaScript 프로그래밍 언어 표준 ECMA-262의 하위 집합입니다. 대부분의 애플리케이션에서는 JSON의 구문 분석이 필요하며, restful API나 데이터 직렬화가 필요한 애플리케이션 등이 해당됩니다.
자바 생태계에서는 JSON 데이터를 처리하는 데 가장 인기 있는 두 라이브러리가 Jackson과 Gson입니다. 두 라이브러리 모두 널리 사용되며 독특한 장점을 제공합니다. 본 문서는 각 라이브러리의 기능을 다양한 매개변수로 탐색하기 위해 극단적인 예제를 사용합니다.
Jackson과 Gson 간단 소개
Jackson
Jackson은 FasterXML에서 개발되었으며, Spring Boot와 같은 기업용 애플리케이션 및 프레임워크에서 사용됩니다. 이는 JSON 데이터의 구문 분석, 직렬화 및 역직렬화를 제공합니다. 다음 기능으로 이 라이브러리가 개발자들 사이에서 인기를 끌게 되었습니다:
- Jackson은 Spring Boot에서 기본 JSON 처리 라이브러리로 사용되어 대부분의 경우 수동 구성을 제거합니다.
- TypeReference 또는 JavaType를 사용하여 일반 유형으로 JSON 역직렬화를 용이하게 합니다.
- 다른 주석을 제공하여 직렬화 및 역직렬화 동작을 사용자 정의할 수 있습니다. 예를 들어,
@JsonProperty(name)
은 수신 키와 실제 Java POJO 필드 간의 매핑을 원활하게 합니다. - 그것은 양방향 데이터 바인딩 (JSON에서 POJO로 및 그 반대로), 스트리밍 API (API가 JSON을 POJO로 읽음) 및 트리 모델 파싱(메모리 내 JSON 객체의 맵)을 위한 광범위하고 견고한 지원을 제공합니다.
- Jackson 라이브러리는 메모리 오버헤드를 최소화하고 직렬화/역직렬화( JSON에서 POJO로 및 그 반대로)를 최적화하여 높은 성능을 제공합니다.
- Jackson은 XML, YAML 처리 및 Kotlin, scala 특정 기능과 같은 추가 모듈을 지원합니다.
@JsonTypeInfo
및@JsonSubTypes
와 같은 주석은 다형 타입을 처리합니다.- 역방향 및 순방향 호환성으로 인해 JSON 데이터의 누락된 또는 추가된 필드를 처리합니다.
- Jackson은 불변 객체 및 생성자를 사용하는 클래스를 지원하며 빌더 패턴을 사용하는 경우도 포함됩니다.
ObjectMapper
클래스는 스레드 안전하므로 멀티스레드 응용 프로그램에서 효율적인 사용이 가능합니다.
Gson
Gson 은 Google에 의해 개발되었으며 JSON을 Java 객체 (POJO)로 변환하고 그 반대로 변환하기 위해 설계되었습니다. 작은 응용 프로그램에 빠른 구현이 필요한 경우 간단하고 이상적으로 사용할 수 있습니다. 이 오픈 소스 라이브러리는 다음 주요 기능을 제공합니다:
- Gson은 외부 종속성이 최소화되어 통합하기 쉽습니다.
- 그것은 중첩된 객체와 목록, 맵, 사용자 지정 클래스와 같은 복잡한 데이터 유형을 지원합니다.
- TypeToken을 사용하여 JSON을
List<T>
,Map<K,V>
와 같은 일반 컬렉션으로 역직렬화할 수 있습니다. - Gson 라이브러리의 JsonSerializer 및 JsonDeserializer 인터페이스를 통해 사용자 정의 구현이 가능합니다.
- 기본적으로 JSON 출력에서는 null 값이 제외되며 필요한 경우 출력에 null 값이 포함될 수 있습니다.
- 어노테이션
@SerializedName
은 JSON 키를 다른 이름을 가진 Java 필드에 매핑합니다. - Gson 객체는 스레드 안전하며, 따라서 멀티스레드 응용 프로그램에서 사용할 수 있습니다.
- GsonBuilder 클래스는 필드에 대해 사용자 정의 네이밍 정책을 적용할 수 있습니다. 예를 들어,
FieldNamingPolicy.IDENTITY
는 필드 이름이 변경되지 않는 기본 정책입니다.
이 비교에서 고려된 특수 케이스
Feature | Jackson | GSON |
---|---|---|
추가 필드 |
기본적으로 무시되며, 구성 가능합니다. |
기본적으로 무시됩니다. |
null 값 |
@JsonInclude를 지원합니다. |
.serializeNulls()를 필요로합니다. |
순환 참조 |
@JsonIdentityInfo를 사용하여 지원됩니다. |
직접적으로 지원되지 않습니다. |
데이터 처리 |
Java 8 날짜 API를 모듈과 함께 지원합니다. |
사용자 정의 유형 어댑터가 필요합니다. |
다형성 |
@JsonTypeInfo와 내장되어 있습니다. |
사용자 정의 역직렬화 로직이 필요합니다. |
Jackson 및 Gson 라이브러리와 비교 대상으로 고려된 입력 JSON은 GitHub에 있습니다.
JSON의 모델 클래스 표현은 GitHub에 있습니다.
Jackson 구현
위의 JSON은 아래의 Jackson 라이브러리를 사용하여 Java 객체로 변환됩니다:
<!-- Jackson START-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.18.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.18.2</version>
</dependency>
<!-- Jackson END-->
Jackson 라이브러리를 사용한 JSON 파싱 main 클래스:
public class JacksonJsonMain {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
//Jackson Support for LocalDate using jackson-datatype-jsr310
mapper.registerModule(new JavaTimeModule());
//Configuration to ignore extra fields
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// Deserialize the JSON
EmployeeModelData employeeModelData = mapper.readValue(json, EmployeeModelData.class);
Employee employee=employeeModelData.getEmployee();
// display Json fields
System.out.println("Jackson Library parsing output");
System.out.println("Employee Name: " + employee.getName());
System.out.println("Department Name: " + employee.getDepartment().getName());
System.out.println("Skills: " + employee.getSkills());
System.out.println("Team Members Count: " + employeeModelData.getTeamMembers().size());
}
}
위 클래스의 출력은 다음과 같습니다:
Gson 구현
위의 JSON을 Java 객체로 변환하기 위해 사용된 Gson 종속성은 다음과 같습니다:
<!--GSON START -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.11.0</version>
</dependency>
<!--GSON END -->
GSON 라이브러리를 사용한 JSON 파싱 main 클래스:
public class GsonJsonMain {
public static void main(String[] args) {
Gson gson = new GsonBuilder()
.registerTypeAdapter(LocalDate.class, new LocalDateAdapter()) // Register LocalDate adapter
.serializeNulls() // Handle null values
.setPrettyPrinting() // Pretty print JSON
.create();
// Deserialize the JSON
EmployeeModelData data = gson.fromJson(json, EmployeeModelData.class);
// Print Employee information
System.out.println("GSON Library parsing output");
System.out.println("Employee Name: " + data.getEmployee().getName());
System.out.println("Department Name: " + data.getEmployee().getDepartment().getName());
System.out.println("Skills: " + data.getEmployee().getSkills());
System.out.println("Team Members Count: " + data.getTeamMembers().size());
}
}
위 main 클래스의 출력은 다음과 같습니다:
어떤 것을 선택해야 할까요?
Jackson은 높은 성능을 제공하므로 프로젝트가 복잡한 데이터 구조나 대규모 데이터 세트를 다룰 때 사용해야 하며, Gson은 데이터 세트가 작고 데이터 구조가 단순할 때 사용해야 합니다.
결론
두 라이브러리는 위의 데이터셋을 효과적으로 처리할 수 있으며 JAVA에서 JSON 파싱을 처리하는 데 우수합니다. 위에서 언급된 비교는 프로젝트 요구사항에 따라 적절한 라이브러리를 선택하는 데 도움이 됩니다.
위에서 언급된 코드 스니펫은 GitHub 저장소에서 확인할 수 있습니다.
Jackson과 Gson 사이의 자세한 비교는 Baeldung에서 확인할 수 있습니다. Jackson 공식 문서에서는 Jackson의 기능과 구성에 대한 깊은 정보를 제공합니다. 마찬가지로, Gson 공식 문서는 자세한 구현 가이드를 제공합니다.
Source:
https://dzone.com/articles/jackson-vs-gson-edge-cases-json-parsing-java