Java/Short 개발

[Java/Short] Object to Map 변환하는 방법 : Uncheked Cast, Jackson 라이브러리 활용

adjh54 2024. 11. 19. 22:52
728x170
해당 글에서는 객체(Object)를 맵(Map) 형태로 변환하는 다양한 방법에 대해 알아봅니다.




1) Object to Map


 💡 Object to Map

- 객체를 Map 형태로 변환하는 이유는 여러 목적으로 가지고 있습니다.
- 일반적으로 Object 형태의 객체를 접근하는 방식을 좀 더 편하게 이용하기 위해서 키-값 쌍으로 이루어진 Map 형태로 데이터를 접근하는데 유용합니다.

Converting Object To Map in Java | Baeldung
 

1. 테스트 데이터 구성


💡 테스트 데이터 구성

- 해당 데이터 구조는 “userInfo”라는 키 내에 properties, additionalInfo, preferences 값으로 구성이 되어 있습니다.

- properties는 사용자 정보를 담는 Map으로 구성이 되어 있습니다.
- additionalInfo는 사용자의 추가 정보를 담는 Map으로 구성이 되어 있습니다.
- preference는 사용자의 선호 사항 정보가 담긴 Map으로 구성이 되어 있는 구조입니다.

- 해당 구성된 데이터를 콘솔로 출력하였을 때 Object로 출력됨을 확인하였습니다.
Map<String, Object> userInfo = new HashMap<>();

// PROPERTIES 데이터 생성
Map<String, Object> properties = new HashMap<>();
properties.put("name", "홍길동");
properties.put("age", 30);
properties.put("email", "hong@example.com");
properties.put("address", "서울시 강남구");
properties.put("phoneNumber", "010-1234-5678");

// 추가 정보 생성
Map<String, Object> additionalInfo = new HashMap<>();
additionalInfo.put("occupation", "개발자");
additionalInfo.put("yearsOfExperience", 5);
additionalInfo.put("skills", Arrays.asList("Java", "Spring", "SQL"));

// 선호 사항 추가
List<String> preferences = Arrays.asList("coffee", "coding", "hiking");

// 상위 userInfo에 모든 정보 추가
Map<String, Object> topLevelUserInfo = new HashMap<>();
topLevelUserInfo.put("properties", properties);
topLevelUserInfo.put("additionalInfo", additionalInfo);
topLevelUserInfo.put("preferences", preferences);

userInfo.put("userInfo", topLevelUserInfo);

 
 

2. 테스트 데이터 확인


💡 테스트 데이터 확인

- 위에서 구성한 데이터는 아래와 같은 Object 형태의 구조로 출력이 됩니다.
{
	properties={
		address=서울시 강남구, 
		phoneNumber=010-1234-5678, 
		name=홍길동, 
		age=30, 
		email=hong@example.com
	},
	additionalInfo={
		skills=[Java, Spring, SQL], 
		occupation=개발자, 
		yearsOfExperience=5
	}, 
	preferences=[coffee, coding, hiking], 
}

 

💡 [참고] Object 구조와 JSON 구조는 어떻게 다른가?

1. 키-값 구분자: Object 구조는 '='를 사용하고, JSON은 ':'를 사용합니다.
2. 문자열 표시: Object 구조는 따옴표가 없고, JSON은 키와 문자열 값에 큰따옴표를 사용합니다.
3. 배열 표시: Object 구조는 대괄호만 사용하고, JSON은 대괄호와 쉼표를 사용합니다.
4. 중괄호 사용: Object 구조는 최상위 레벨에서만 중괄호를 사용하고, JSON은 모든 객체에 중괄호를 사용합니다.
5. 쉼표 사용: Object 구조는 쉼표를 사용하지 않고, JSON은 요소들을 구분하기 위해 쉼표를 사용합니다.
// Object 구조 : Java의 Map 출력 형태
{
	properties={
		address=서울시 강남구, 
		phoneNumber=010-1234-5678, 
		name=홍길동, 
		age=30, 
		email=hong@example.com
	},
	additionalInfo={
		skills=[Java, Spring, SQL], 
		occupation=개발자, 
		yearsOfExperience=5
	}, 
	preferences=[coffee, coding, hiking], 
}

// JSON 구조
{
    "properties": {
        "address": "서울시 강남구",
        "phoneNumber": "010-1234-5678",
        "name": "홍길동",
        "age": 30,
        "email": "hong@example.com"
    },
    "additionalInfo": {
        "skills": ["Java", "Spring", "SQL"],
        "occupation": "개발자",
        "yearsOfExperience": 5
    },
    "preferences": ["coffee", "coding", "hiking"]
}

 
 
 

 

2) 변환 방법


💡 변환 방법

- 아래와 같이 구성된 useInfo 객체 내에서 Map으로 변환하여 값을 추출하는 방법에 대해 알아봅니다.
// 테스트용 USERINFO 데이터 생성
Map<String, Object> userInfo = new HashMap<>();

// PROPERTIES 데이터 생성
Map<String, Object> properties = new HashMap<>();
properties.put("name", "홍길동");
properties.put("age", 30);
properties.put("email", "hong@example.com");
properties.put("address", "서울시 강남구");
properties.put("phoneNumber", "010-1234-5678");

// 추가 정보 생성
Map<String, Object> additionalInfo = new HashMap<>();
additionalInfo.put("occupation", "개발자");
additionalInfo.put("yearsOfExperience", 5);
additionalInfo.put("skills", Arrays.asList("Java", "Spring", "SQL"));

// USERINFO에 PROPERTIES와 추가 정보 추가
userInfo.put("properties", properties);
userInfo.put("additionalInfo", additionalInfo);

// 선호 사항 추가
List<String> preferences = Arrays.asList("coffee", "coding", "hiking");
userInfo.put("preferences", preferences);

log.debug("userInfo: {}", userInfo);

// 값을 추출합니다.
Object userInfoObj = userInfo.get("userInfo");

 

💡 [참고] 아래와 같은 값이 구성되었습니다.
{
	properties={
		address=서울시 강남구, 
		phoneNumber=010-1234-5678, 
		name=홍길동, 
		age=30, 
		email=hong@example.com
	},
	additionalInfo={
		skills=[Java, Spring, SQL], 
		occupation=개발자, 
		yearsOfExperience=5
	}, 
	preferences=[coffee, coding, hiking], 
}

 
 

1. Unchecked Cast 방법


💡 Unchecked Cast 방법

- Object를 특정 타입으로 변환할 때 사용되는 간단한 방법입니다. 그러나 타입의 안정성이 보장되지 않기에 주의가 필요한 방법입니다.
- 그렇기에 가능하면 제네릭이나 instanceof 검사를 통해 타입 안정성을 높이는 것이 좋습니다.
특징 설명
간단성 코드가 간결하고 이해하기 쉬움
컴파일러 경고 타입 안정성 문제로 경고 발생
런타임 에러 위험 잘못된 캐스팅 시 ClassCastException 발생 가능
성능 추가 라이브러리나 복잡한 로직 불필요, 효율적

 

💡 해당 예시에서는 userinfo.properties.name 값을 추출하는 과정을 Unchecked Cast를 통해서 적용한 방법입니다.
// 값을 추출합니다.
Object userInfoObj = userInfo.get("userInfo");

/*
 * Unchecked Cast 방법
 */
Map<String, Object> useInfoMap = (Map<String, Object>) userInfoObj;
Map<String, Object> propertiesMap = (Map<String, Object>) useInfoMap.get("properties");
String name = propertiesMap.get("name").toString();
log.debug("name: {}", name);

 
 

💡 해당 예시에서는 userinfo.properties.name 값을 추출하는 과정을 Unchecked Cast와 제네릭이나 instanceof 검사를 통해서 적용한 방법입니다.

- 타입의 안정성을 보장하지만, 불 필요하게 처리해야 하는 코드들이 많은 문제가 있습니다.
// 값을 추출합니다.
Object userInfoObj = userInfo.get("userInfo");

// instanceof 검사와 제네릭을 사용한 방법
if (userInfoObj instanceof Map) {
    Map<String, Object> userInfoMap = (Map<String, Object>) userInfoObj;
    Object propertiesObj = userInfoMap.get("properties");

    if (propertiesObj instanceof Map) {
        Map<String, Object> propertiesMap = (Map<String, Object>) propertiesObj;
        Object nameObj = propertiesMap.get("name");

        if (nameObj instanceof String) {
            String name = (String) nameObj;
            log.debug("name: {}", name);
        } else {
            log.error("Name is not a String");
        }
    } else {
        log.error("Properties is not a Map");
    }
} else {
    log.error("UserInfo is not a Map");
}

 
 

2. Jackson 라이브러리 활용 방법


💡 Jackson 라이브러리 활용 방법

- Jackson 라이브러리를 사용하면 Object를 JSON으로, 그리고 JSON을 Map으로 변환할 수 있습니다.
public ResponseEntity<Object> naverLogin(){

	Object userInfoObj = userInfo.get("userInfo");
	// 2. Jackson 라이브러리 사용 방법
	try {
	    Map<String, Object> userInfoMap = this.objectToMap(userInfoObj);
	    Map<String, Object> propertiesMap = this.objectToMap(userInfoMap.get("properties"));
	    String name = propertiesMap.get("name").toString();
	    log.debug("name: {}", name);
	} catch (Exception e) {
	    log.error(e.getMessage());
	}
}
/**
 * Jackson 라이브러리를 활용해서 Map 형태로 변환합니다. : object to map
 * @param obj
 * @return
 */
private Map<String, Object> objectToMap(Object obj) {
    ObjectMapper mapper = new ObjectMapper();
    return mapper.convertValue(obj, new TypeReference<>() {
    });
}

 

💡 아래와 같이 결과를 추출했습니다.

 
 

💡 [참고] Jackson 라이브러리에 대해 궁금하시면 아래의 글을 참고하시면 도움이 됩니다.
 

[Java] Spring Boot 환경에서 Jackson 모듈 활용하기 : JSON 파싱, 직렬화, 역 직렬화, JSON 파일 읽어오기/

해당 글에서는 Spring Boot 환경에서 Jackson 라이브러리를 활용하는 방법에 대해서 알아봅니다. 1) Jackson 💡 Jackson - JSON 데이터 작업을 하기 위한 인기 있는 Java 라이브러리입니다. - JSON 파일을 읽거

adjh54.tistory.com

 
 
 
 
오늘도 감사합니다 😀
 
 

그리드형