반응형
해당 글에서는 객체(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 라이브러리에 대해 궁금하시면 아래의 글을 참고하시면 도움이 됩니다.
오늘도 감사합니다 😀
반응형