JAVA

[JAVA] Gson의 제한사항과 문제 해결

인생아 2024. 12. 14. 22:18
반응형

Gson의 제한사항과 문제 해결은 실무에서 Gson을 사용할 때 발생할 수 있는 문제점과 이를 해결하는 방법에 대해 다룹니다. 특히, 순환 참조, JSON 키/값이 없는 경우, 예외 상황 디버깅은 자주 직면하는 이슈입니다. 각각의 문제와 해결 방법을 예제와 함께 상세히 설명합니다.

순환 참조 문제와 해결 방법
Gson으로 객체를 JSON으로 변환할 때, 순환 참조(Circular Reference)가 있는 경우 StackOverflowError가 발생할 수 있습니다. 이는 부모 객체가 자식 객체를 참조하고, 자식 객체가 다시 부모 객체를 참조하는 구조 때문입니다.

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

class Employee {
    String name;
    Department department;

    public Employee(String name, Department department) {
        this.name = name;
        this.department = department;
    }
}

class Department {
    String name;
    Employee employee;

    public Department(String name) {
        this.name = name;
    }
}

public class CircularReferenceExample {
    public static void main(String[] args) {
        Department department = new Department("개발팀");
        Employee employee = new Employee("김철수", department);
        department.employee = employee;

        // 기본 Gson 사용 시 StackOverflowError 발생
        Gson gson = new Gson();
        // String json = gson.toJson(department); // 오류 발생

        // 순환 참조 해결: GsonBuilder 사용
        Gson safeGson = new GsonBuilder().serializeNulls().setPrettyPrinting().create();
        String json = safeGson.toJson(department);
        System.out.println(json);
    }
}

해결 방법

  1. GsonBuilder의 serializeNulls()와 setExclusionStrategies()를 사용해 순환 참조를 방지합니다.
  2. @Expose 또는 @JsonAdapter와 같은 어노테이션으로 특정 필드를 제외합니다.
import com.google.gson.annotations.Exclude;

class SafeDepartment {
    String name;
    @Exclude transient Employee employee; // JSON 직렬화에서 제외
}
반응형

JSON 키/값이 없는 경우 처리
JSON 데이터에서 특정 키/값이 없을 때 발생하는 문제를 안전하게 처리하려면 기본 값을 설정하거나 JsonElement를 사용해야 합니다.

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

public class MissingKeyHandling {
    public static void main(String[] args) {
        String jsonData = "{ \"name\": \"서울\", \"population\": 9733509 }";

        Gson gson = new Gson();
        JsonObject jsonObject = JsonParser.parseString(jsonData).getAsJsonObject();

        String name = jsonObject.has("name") ? jsonObject.get("name").getAsString() : "알 수 없음";
        String mayor = jsonObject.has("mayor") ? jsonObject.get("mayor").getAsString() : "정보 없음";

        System.out.println("도시 이름: " + name);
        System.out.println("시장: " + mayor);
    }
}

해결 방법

  1. JsonObject.has()를 사용해 키 존재 여부를 확인합니다.
  2. 데이터 모델 클래스에 기본 값을 설정합니다.
class City {
    String name = "알 수 없음";
    int population = 0;
    String mayor = "정보 없음";
}

예외 상황 디버깅과 해결법
Gson을 사용하다 보면, JSON 형식 오류, 데이터 타입 불일치, 예기치 않은 null 값 등 다양한 예외가 발생할 수 있습니다. 이를 디버깅하려면 다음과 같은 전략을 사용할 수 있습니다.

  1. try-catch 블록으로 오류를 잡아 디버깅 메시지를 출력합니다.
  2. JsonSyntaxExceptionJsonParseException을 명확히 처리합니다.
  3. 디버깅을 위해 JSON 데이터를 PrettyPrinting으로 포맷팅해 확인합니다.
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;

public class DebuggingExample {
    public static void main(String[] args) {
        String invalidJson = "{ \"name\": \"서울\", \"population\": \"invalid_number\" }";

        Gson gson = new Gson();

        try {
            City city = gson.fromJson(invalidJson, City.class);
            System.out.println(city.name + "의 인구는 " + city.population);
        } catch (JsonSyntaxException e) {
            System.out.println("JSON 구문 오류: " + e.getMessage());
        }
    }
}

해결 방법

  1. 유효성 검사: JSON 데이터의 스키마를 미리 검증합니다.
  2. 디버깅 도구: Gson의 fromJson()toJson() 호출 시 문제가 있는 데이터를 로깅합니다.
  3. 커스텀 예외 처리: 비정상 데이터를 로깅하거나 예외를 사용자 정의 메시지로 반환합니다.

Gson 공식 문서 및 가이드

반응형