공통API JSON 유틸리티(직접구현)
API 요약
JAVA 에서 핸들링
❗파싱되면 깊은레벨로 접근못함
💡 jsonToMap() 또는 jsonToListMap() 으로 파싱된 데이터는 각각 가장 첫번째 키만 접근 가능함.
💡 나머지는 문자열 형태로 저장되어있기 때문임.
HomeController.java
import 패키지.util.HttpUtil;
import 패키지.util.StringUtil;
getYarnResourceData()
private static final YARN_RESOURCE_METRIC = "http://주소:포트/ws/v1/cluster/metrics/";
private static final YARN_RESOURCE_INFO = "http://주소:포트/ws/v1/cluster/info/";
private static final YARN_RESOURCE_APP = "http://주소:포트/ws/v1/cluster/app/";
/*********************
* GET Yarn Resource Manager REST API
* 응답된 JSON 결과를 파싱하고 프론트로 넘긴다.
*
* @param
* @return List<Map<String, Object>>
* @throws
*********************/
@ResponseBody
@RequestMapping(value="/getYarnResourceData",method = RequestMethod.POST)
public List<Map<String, Object>> getYarnResourceData() throws Exception{
logger.info("HomeController getYarnResourceData start >>");
List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
try {
// Yarn Resource Manager REST API (JSON ROOT KEY)
// 최상위 key는 공식홈페이지에서 원하는 API 확인
String[] yarnResource = {"clusterMetrics", "clusterInfo"};
for(int i=0; i<yarnResource.length; i++) {
//STEP1. GET JSON
String responseData = ""; //응답데이터
switch (yarnResource[i]) {
case "clusterMetrics":
responseData = HttpUtil.connectGET(YARN_RESOURCE_METRIC);
break;
case "clusterInfo":
responseData = HttpUtil.connectGET(YARN_RESOURCE_INFO);
break;
}
System.out.println((yarnResource[i] + " => GET: " + responseData);
//Map 으로 사용하고싶은경우 ==> jsonToMap(responseData);
//List<Map> 으로 사용하고싶은경우 ==> jsonToListMap(responseData);
resultList.add(jsonToListMap(responseData));
}
} catch (Exception e) {
e.printStackTrace();
}
return resultJSON;
}
❗과정
💡 JSON 문자열을 받아서 가공 후 리턴한다.
💡 - HTTP 유틸 호출
💡 - JSON 유틸 호출
HttpUtil.java
참고 포스팅
자바API HTTP 핸들링 유틸
StringUtil.java
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
mapToStrJson() : JSON맵 > JSON 전문
/*********************
* map 객체를 js가 핸들링 할 수 있는 완전한 json 전문으로 변환<br>
*
* @param mapJson - Map<String, Object>
* @return String - 이스케이프 처리된 문자열
* @throws
*********************/
public static String mapToStrJson(Map<String, Object> mapStrJson) {
StringBuilder jsonStringBuilder = new StringBuilder();
jsonStringBuilder.append("{");
boolean firstEntry = true; //첫회 skip
for (Map.Entry<String, Object> entry : mapStrJson.entrySet()) {
if (!firstEntry) {
jsonStringBuilder.append(",");
}
jsonStringBuilder.append("\"").append(entry.getKey()).append("\":");
Object value = entry.getValue();
if (value instanceof String) {
jsonStringBuilder.append("\"").append(value).append("\"");
} else if(value instanceof Double) {
// Gson 라이브러리의 키값이 int 형은 double 로 처리
jsonStringBuilder.append("\"").append(value).append("\"");
} else {
jsonStringBuilder.append(value);
}
firstEntry = false;
}
jsonStringBuilder.append("}");
String jsonString = jsonStringBuilder.toString();
System.out.println(jsonString);
return jsonString;
}
jsonToMap() : JSON문자열 > 맵
/*********************
* json 형태의 문자열을 맵 객체로 변환<br>
*
* @param json 형태의 문자열
* @return Map<String, Object>
* @throws
*********************/
public static Map<String, Object> jsonToMap(String strJson) {
Map<String, Object> mapJson = new HashMap<String, Object>();
JsonObject jsonObject = JsonParser.parseString(resJson).getAsJsonObject();
for(String key : jsonObject.keySet()) {
//String strKey = key; //키
JsonElement jsonElement = jsonObject.get(key);
Object value = getJsonToObj(jsonElement);
mapJson.put(key, value);
}
return mapJson;
}
❗INPUT
// String - 문자열 제이슨 전문 {"key1": {"key1_1": "value1_1","key1_2": "999","key1_3": {"key3_1": "value3_1"}}}
❗OUTPUT
// Map<String, Object> - 맵객체로 변환완료(출력 결과) {key1={key1_1=value1_1, key1_2=999, key1_3={key3_1=value3_1}}}
💡 - 자바에서는 Map 객체안에 저장되면 중첩된 내부 키는 접근못한다. (문자열일 뿐이다.)
💡 - 즉, key1 만 접근 가능하다.
💡 - 접근하고 싶다면 내부의 값도 변환하여 별도 처리가 필요하다.❗JSP 에서 활용
var paramData = {}; fnSyncAjax("POST", "/chart/getYarnResource", paramData, function(reulst) { //$.each(result, function(idx, data)) {} console.log(reulst.key1); console.log(reulst.key1_1); console.log(reulst.key1_2); console.log(reulst.key1_3.key3_1); });
💡 - JS에서는 맵객체로 넘어오면 . 체이닝으로 접근가능하다.
jsonToListMap() : JSON 전문 > 리스트맵
/*********************
* json 형태의 문자열을 리스트맵 객체로 변환<br>
*
* @param json 형태의 문자열
* @return List<Map<String, Object>>
* @throws
*********************/
public static List<Map<String, Object>> jsonToListMap(String strJson) {
List<Map<String, Object>> listJson = new ArrayList<Map<String, Object>>();
JsonObject jsonObject = JsonParser.parseString(resJson).getAsJsonObject();
for(String key : jsonObject.keySet()) {
//String strKey = key; //키
JsonElement jsonElement = jsonObject.get(key);
Object value = getJsonToObj(jsonElement);
Map<String, Object> mapJson = new HashMap<String, Object>();
mapJson.put(key, value);
listJson.add(mapJson);
}
return listJson;
}
❗INPUT
// String - 문자열 제이슨 전문 {"key1": {"key1_1": "value1_1","key1_2": "999","key1_3": {"key3_1": "value3_1"}}}
❗OUTPUT
// List<Map<String, Object>> - 리스트맵객체로 변환완료(출력 결과) [{key1={key1_1=value1_1, key1_2=999, key1_3={key3_1=value3_1}}}]
💡 - 리스트안에 저장되었다. 그리고 아래 내용은 이전과 동일하다.
💡 - Map 객체안에 저장되면 중첩된 내부 키는 접근못한다. (문자열일 뿐이다.)
💡 - 즉, key1 만 접근 가능하다.
💡 - 접근하고 싶다면 내부의 값도 변환하여 별도 처리가 필요하다.❗JSP 에서 활용
var paramData = {}; fnSyncAjax("POST", "/chart/getYarnResource", paramData, function(reulst) { //$.each(result, function(idx, data)) {} console.log(reulst[0].key1); console.log(reulst[0].key1.key1_1); console.log(reulst[0].key1.key1_2); console.log(reulst[0].key1.key1_3.key3_1); });
💡 - JS에서는 맵객체로 넘어오면 . 체이닝으로 접근가능하다.
🎆 getJsonToObj() : JSON엘리먼트 > 오브젝트
/*********************
* com.google.gson.JsonElement.JsonObject 객체를<br>
* Object 타입으로 변환<br>
* 프론트에서 핸들링시 다양한 타입을 꺼낼 수 있도록 처리한다.<br>
*
* @param com.google.gson.JsonElement
* @return Object
* @throws
*********************/
public static Object getJsonToObj(JsonElement jsonElement) {
//기본적인 원시 타입인지 확인
if (jsonElement.isJsonPrimitive()) {
if (jsonElement.getAsJsonPrimitive().isString()) {
return jsonElement.getAsString();
} else if (jsonElement.getAsJsonPrimitive().isNumber()) {
return jsonElement.getAsNumber();
} else if (jsonElement.getAsJsonPrimitive().isBoolean()) {
return jsonElement.getAsBoolean();
}
}
//객체인경우 재귀호출로 원시타입까지 처리
else if (jsonElement.isJsonObject()) {
JsonObject jsonObject = jsonElement.getAsJsonObject();
Map<String, Object> nestedMap = new HashMap<String, Object>();
for (String key : jsonObject.keySet()) {
JsonElement resultElement = jsonObejct.get(key);
nestedMap.put(key, getJsonToObj(resultElement));
}
return nestedMap;
}
return null;
}
(중요) getNestedValue() : Map > 중첩된 값 꺼내고 Map
/*********************
* map 객체의 중첩된 특정 키에 접근 후 맵 객체 리턴<br>
*
* @param json 형태의 문자열
* @return List<Map<String, Object>>
* @throws
*********************/
public static Map<String, Object> getMapToNestedMap(Map<String, Object> resultMap, StringnestedKey) {
Object nestedValue = resultMap.get(nestedKey);
if (nestedValue instanceof Map) {
Map<String, Object> nestedMap = (Map<String, Object>) nestedValue;
return nestedMap;
}
return null;
}
💡 맵안에 저장된 JSON 키안에 값이 또 객체를 가졌다면 중첩된 값을 얻는 함수가 필요하다.
아래 함수로 Object를 얻을 수 있다.
❗INPUT
// Map<String, Object> - 맵 객체 {key1={key1_1=value1_1, key1_2=999, key1_3={key3_1=value3_1}}}
❗OUTPUT
// Map<String, Object> - 특정 키의 값에 저장된 JSON 으로 맵객체 변환 {key1_1=value1_1, key1_2=999, key1_3={key3_1=value3_1}}
💡 Map 객체안에 중첩된 내부 키에 접근하고 그 값의 JSON 을 MAP 으로 만들었다.
❗Example
💡 아래와 같이 사용한다.// JSON 데이터가 들어있는 resultMap 이라고 가정 // {"key1": {"key1_1": "value1_1","key1_2": "999","key1_3": {"key3_1": "value3_1"}}} Map<String, Object> resultMap= new HashMap<String, Object>(); // API 사용1 resultMap = StringUtil.getMapToNestedMap(resultMap, "key1"); System.out.println(resultMap); // {key1_2=999, key1_1=value1_1, key1_3={key3_1=value3_1}} // API 사용2 resultMap = StringUtil.getMapToNestedMap(resultMap, "key1_3"); System.out.println(resultMap); // {key3_1=value3_1} System.out.println(resultMap.get("key3_1")); // value3_1
Leave a comment