JS JSON 핸들링
JSON 핸들링
JSON 형태 예제1 (document)
{
"documnet": [
{
"msg": "성공",
"result": [
"data1",
"data2"
],
"address": [
{
"data2": "데이터2의 값 홍길동주소",
"data1": "데이터1의 값 홍길동"
},
{
"data2": "데이터2의 값 박명수주소",
"data1": "데이터1의 값 박명수"
}
],
"language": [
{
"언어": "일본어",
"언어2": "카타카나",
"언어1": "히라가나"
},
{
"언어": "중국어",
"언어2": "번체",
"언어1": "간체"
}
],
"status": 200
}
],
"etc": {
"name": "기타"
}
}
JSON 형태 예제2 (clusterMetrics)
{
"clusterMetrics": {
"appsSubmitted": 1,
"appsCompleted": 25000,
"appsPending": 0,
"appsRunning": 0,
"appsFailed": 1,
"appsKilled": 1,
"reservedMB": 0,
"availableMB": 17408,
"allocatedMB": 0,
"reservedVirtualCores": 0,
"availableVirtualCores": 7,
"allocatedVirtualCores": 1,
"containersAllocated": 0,
"containersReserved": 0,
"containersPending": 0,
"totalMB": 17408,
"totalVirtualCores": 8,
"totalNodes": 1,
"lostNodes": 0,
"unhealthyNodes": 0,
"decommissioningNodes": 0,
"decommissionedNodes": 0,
"rebootedNodes": 0,
"activeNodes": 1,
"shutdownNodes": 0
}
}
(JSP 처리) EL
(JSON) JSON형태 String 조작 👎❌
/* java (백앤드) */
String strJsonStr =
"{" +
" \"documnet\": [" +
" {" +
" \"status\": 200," +
" \"msg\": \"성공\"," +
" \"result\": [" +
" \"data1\"," +
" \"data2\"" +
" ]," +
" \"address\": [" +
" {" +
" \"data2\": \"데이터2의 값 홍길동주소\"," +
" \"data1\": \"데이터1의 값 홍길동\"" +
" }," +
" {" +
" \"data2\": \"데이터2의 값 박명수주소\"," +
" \"data1\": \"데이터1의 값 박명수\"" +
" }" +
" ]," +
" \"language\": [" +
" {" +
" \"언어\": \"일본어\"," +
" \"언어2\": \"카타카나\"," +
" \"언어1\": \"히라가나\"" +
" }," +
" {" +
" \"언어\": \"중국어\"," +
" \"언어2\": \"번체\"," +
" \"언어1\": \"간체\"" +
" }" +
" ]" +
" }" +
" ]," +
" \"etc\": {" +
" \"name\": \"기타\"" +
" }" +
"}";
SONObject jsonObject = new JSONObject(strJsonStr);
SONObject etcObject = jsonObject.getJSONObject("etc");
tring etc = etcObject.getString("name");
ystem.out.println(etc);
odel.addAttribute("type0", strJsonStr);
<!-- JSP (프론트) -->
<!-- String (for Perfect ORIGNAL JSON) -->
<h3><i>완전한 json 문자열 전달</i></h3>
<ul>
<li><b>JSON String: </b> ${type0}</li>
<%-- type0 변수에 저장된 JSON 문자열을 EL을 사용하여 받아옴 --%>
<%
String strJson = (String) request.getAttribute("type0");
JSONObject jsonObject = new JSONObject(strJson);
JSONObject etcObject = jsonObject.getJSONObject("etc");
String etc = etcObject.getString("name");
System.out.println("etc: " + etc);
%>
<li><b>etc : </b> ${etc}</li>
❗JSON을 EL로 표현하는것은 사용하지말자…
💡etc 객체의 키(name)값이 출력되지 않는다..
💡내부 엔진의 문제인듯 하다. 이 방법으로 절대 시간 소비하지말자 … 꼭.. 서버에서 처리하자..❗챗GPT 답변
- JSP 문법 오류: JSP 코드 내에서 ${}로 값을 가져오는 부분에 문법적인 오류가 있는지 확인해야 합니다. <% %> 스크립트릿과 EL 표현식을 혼합해서 사용하면 문제가 발생할 수 있습니다.
- ❌ 해당되지 않는다. System.out.println(“etc: “ + etc); 출력되었기에..
- etc 변수가 null이거나 값이 없는 경우: ${etc}로 값을 출력하려면 etc 변수가 올바르게 값을 가지고 있어야 합니다. System.out.println(“etc: “ + etc);가 출력되어도, 변수 값이 null이거나 비어있다면 출력되지 않을 수 있습니다.
- ❌ 해당되지 않는다. String etc 정의가 되었으니까 출력되었겠지.
- JSP 컨테이너 설정: 일부 경우에는 JSP 컨테이너 설정이나 JSP 엔진의 동작 방식에 의해 EL 표현식이 올바르게 해석되지 않을 수 있습니다. 이 경우에는 JSP 컨테이너의 로그를 확인하거나 컨테이너 설정을 검토해야 할 수 있습니다.
- 🤔 이부분으 의심되지만 확인하기 어렵다.
(JSON) List, Map 객체 조작 👍
/* java (백앤드) */
String strJsonStr = "[제이슨 형태 데이터]";
Gson gson = new Gson();
TestDTO testDto = new TestDTO();
testDto = gson.fromJson(strJsonStr, TestDTO.class);
// document (배열)
List<Map<String, Object>> documnet = testDto.getDocumnet();
// etc (기본)
List<Map<String, Object>> type1 = testDto.getDocumnet();
Map<String, Object> type2 = testDto.getEtc();
model.addAttribute("type1", documnet);
model.addAttribute("type2", etc);
<!-- JSP (프론트) -->
<!-- List<Map<String, Object>> -->
<h3><i>document 전달</i></h3>
<c:forEach var="item" items="${type1}">
<ul>
<li><b>document 객체: </b> ${type1}</li>
<li><b>status: </b> ${item.status}</li>
<li><b>msg: </b> ${item.msg}</li>
<li><b>result: </b> ${item.result}</li>
<li><b>address: </b> ${item.address}</li>
<c:forEach var="address" items="${item.address}">
<ul>
<li><b>data1(key): </b> ${address.data1}</li>
<li><b>data2(key): </b> ${address.data1}</li>
</ul>
</c:forEach>
<li><b>language(한글EL불가):</b> ${item.language}</li>
</ul>
</c:forEach>
<hr>
<!-- Map<String, Object> -->
<h3><i>etc 전달</i></h3>
<ul>
<li><b>etc 객체: </b> ${type2}</li>
<p>name: ${type2.name}</p>
</ul>
<hr>
(JSP 처리) Script
(JSON) JSON형태 String 조작 👍
/* java (백앤드) */
String strJsonStr = "[제이슨 형태 데이터]";
model.addAttribute("type0", strJsonStr);
// jsp (프론트)
<script>
$(document).ready(function (){
// 온로드시 백앤드에서 전달받은 JSON 처리
type0 = '${type0}'; // Original JSON String
var parsedData = JSON.parse(type0);
var stastus = parsedData.documnet[0].status;
var msg = parsedData.documnet[0].msg;
var address = parsedData.documnet[0].address[0].data1;
var language = parsedData.documnet[0].language[0].언어;
});
</script>
❗설명
💡 JSON 형태가 완전하면 JSP 에서 조작이 가능하다.
💡 즉, JSON.parse(); 함수가 가능해진다.
⭐⭐⭐ (JSON) List, Map 객체 조작 핵심
❗설명
💡 JSON 형태가 완전하면 JSP 에서 조작이 가능하다.
💡 즉, JSON.parse(); 함수로 조작이 가능해진다.
💡 이, JSON.parse(); 함수를 사용해야 직관적으로 체이닝을 통해 값에 접근이 가능하므로 필수라고 생각한다..❗JSON.parse() 를 사용하기위한 조건
💡 JSON.parse()를 사용하기 위한 조건
- 키는 “” 감싸져야함.
- 값은 “” 감싸져야함.
- 즉, 완벽한 JSON 형태의 문자열을 인수로 사용해야한다.
❗문제점
💡 대부분 Java 에서 핸들링하면 무조건 키와 값의 JSON 형태가 풀리게된다.(“큰따옴표가 지워짐)
💡 값에 숫자가 들어가는 경우에도 “큰따옴표가 없으므로 에러가 발생한다.❗해결방법
💡 해결방법은 입맞대로 가공을 마치면 JS에서 인식할 수 있는 String 으로 가공해주어야 한다.
반드시 아래와 같은 형태로 서버에서 JSP 측으로 전달해야만 한다.// JSON.parse() 사용 불가능 {"clusterInfo": {"appsSubmitted": 1.0,"appsCompleted": 25000.0}} // JSON.parse() 사용 가능 {"clusterInfo": {"appsSubmitted":"1.0","appsCompleted":"25000.0"}}
(JSON) List, Map 객체 조작(1) 자바로 생성한 완벽한 JSON
/* java (백앤드) */
// org.json 패키지를 활용
// 완벽한 JSON 형태의 문자열을 만드는 함수
public static String creatJsonObj1() {
String strJsonObject = "";
JSONObject jsonObject = new JSONObject();
JSONArray resultArray = new JSONArray(); //일반 배열
JSONArray addressArray = new JSONArray(); //객체 배열
resultArray.put("data1");
resultArray.put("data2");
addressArray.put(new JSONObject() );
addressArray.put(new JSONObject() );
jsonObject.put("status", 200);
jsonObject.put("msg", "성공");
jsonObject.put("result", resultArray);
jsonObject.put("address", addressArray);
strJsonObject = (String) jsonObject.toString();
return strJsonObject;
}
// JSP (프론트로) 전달
model.addAttribute("goodJson", creatJsonObj1());
// jsp (프론트)
<script>
$(document).ready(function (){
// 완벽한 JSON 이므로 조작이 가능해진다.
var goodJson = '${goodJson}';
var perffectJson = JSON.parse(goodJson); //이게 가능해진다.
var stastus = perffectJson.status;
var msg = perffectJson.msg;
var address = perffectJson.address[0].data1;
var language = perffectJson.language[0].언어;
});
</script>
(JSON) List, Map 객체 조작(2) 자바로 생성한 완벽한 JSON
String jsonString = "{\"documnet\":[{\"msg\":\"성공\",\"result\":[\"data1\",\"data2\"],\"address\":[{\"data2\":\"데이터2의 값 홍길동주소\",\"data1\":\"데이터1의 값 홍길동\"},{\"data2\":\"데이터2의 값 박명수주소\",\"data1\":\"데이터1의 값 박명수\"}],\"language\":[{\"언어\":\"일본어\",\"언어2\":\"카타카나\",\"언어1\":\"히라가나\"},{\"언어\":\"중국어\",\"언어2\":\"번체\",\"언어1\":\"간체\"}],\"status\":200}]}";
// JSP (프론트로) 전달
model.addAttribute("goodJson2", creatJsonObj1());
// jsp (프론트)
<script>
$(document).ready(function (){
// 완벽한 JSON 이므로 조작이 가능해진다.
var goodJson2 = '${goodJson2}'; //이게 가능해진다.
var perffectJson2 = JSON.parse(goodJson2);
var stastus2 = cluMtData.documnet[0].status;
var msg2 = cluMtData.documnet[0].msg;appsSubmitted,appsSubmitted,
var address2 = cluMtData.documnet[0].address[0].data1;
var language2 = cluMtData.documnet[0].language[0].언어;
});
</script>
(JSON) List, Map 객체 조작(3) 유틸리티로 생성한 JSON (1개처리)
java.lang.reflect.Type mapType2 = new com.google.gson.TypeToken<Map<String, Object>>(){}.getType();
Gson gson2 = new Gson();
Map<String, Object> mapResult2 = new HashMap<String, Object>();
// STEP1. API 요청후 JSON 얻기
//String getYarnJson2 = BlangJsonUtil.getYarnMetrics();
String getYarnJson2 = "{\"clusterMetrics\":{\"appsSubmitted\":1,\"appsCompleted\":25000,\"appsPending\":0,\"appsRunning\":0,\"appsFailed\":1,\"appsKilled\":1,\"reservedMB\":0,\"availableMB\":17408,\"allocatedMB\":0,\"reservedVirtualCores\":0,\"availableVirtualCores\":7,\"allocatedVirtualCores\":1,\"containersAllocated\":0,\"containersReserved\":0,\"containersPending\":0,\"totalMB\":17408,\"totalVirtualCores\":8,\"totalNodes\":1,\"lostNodes\":0,\"unhealthyNodes\":0,\"decommissioningNodes\":0,\"decommissionedNodes\":0,\"rebootedNodes\":0,\"activeNodes\":1,\"shutdownNodes\":0}}";
// STEP2. 얻은 JSON 키값의 데이터타입별로 GSON 라이브러리로 Map<String, Object> 동적처리.
Map<String, Object> mapJson2 = gson2.fromJson(getYarnJson2, mapType2);
// STEP3. ROOT KEY ACCESS
Map<String, Object> accessData2 = (Map<String, Object>) mapJson2.get("clusterMetrics");
// STEP4. JS가 인식가능한 완벽한 JSON 문자열 생성
if (accessData2 != null) {
String resultData2 = BlangJsonUtil.mapToJson(accessData2); // 완벽한 JSON 만들기
mapResult2.put("clusterMetrics", resultData2); // ROOT KEY 이름으로 맵키 생성
}
// JSP (프론트로) 전달
model.addAttribute("mapResult2", mapResult2);
<script>
$(document).ready(function (){
let jsonMetrics2 = '${mapResult2.clusterMetrics}';
if (jsonMetrics2 != null) {
var clusterMetrics = JSON.parse(jsonMetrics2); //함수 성공조건: 완벽한 JSON 문자열이여야 함.
console.log(clusterMetrics.appsRunning);
}
});
</script>
❗완전한 JSON 문자열처리 유틸(mapToJson) 사용시
💡 이렇게 JS에서 사용 가능한 TO-BE 형태로 변한다.Map<String, Object> mapResult = new HashMap<String, Object>(); String resultData = BlangJsonUtil.mapToJson("[파싱한 Map객체]"); mapResult.put("clusterMetrics", resultData);
/* 출력결과 AS-IS */ {clusterMetrics={"appsSubmitted":1.0,"appsCompleted":25000.0}} /* 출력결과 TO-BE*/ {clusterInfo={"appsSubmitted":"1.0","appsCompleted":"25000.0"}}
(JSON) List, Map 객체 조작(4) 유틸리티로 생성한 JSON (n개처리)
✅ BlangJsonUtil.java
/*********************
* Cluster Resource API 요청 (분기처리)<br>
* 요청한 API 별로 <br>
* 이스케이프 처리하여 JSON 형태 데이터를 생성한다.<br>
* @return String 제이슨 형태 문자열
*********************/
public static String getYarnData(String api) {
switch (api) {
case "clusterMetrics":
return getYarnMetrics();
case "clusterInfo":
return getYarnInfo();
}
return null;
}
/*********************
* MAP객체를 JS가 인식할 수 있는 JSON 형태 문자열로 변경<br>
*
* @param mapJson - Map<String, Object> 타입
* @return String 완전한 JSON 형태의 문자열
*********************/
public static String mapToJson(Map<String, Object> mapJson) {
// JSON 문자열 구성
StringBuilder jsonStringBuilder = new StringBuilder();
jsonStringBuilder.append("{");
boolean firstEntry = true;
for (Map.Entry<String, Object> entry : mapJson.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;
}
/*********************
* Cluster Metrics API 요청
*********************/
public static String getYarnMetrics() {
String strJsonStr = "{\"clusterMetrics\":{\"appsSubmitted\":1,\"appsCompleted\":25000,\"appsPending\":0\"appsRunning\":0,\"appsFailed\":1,\"appsKilled\":1,\"reservedMB\":0,\"availableMB\":17408\"allocatedMB\":0,\"reservedVirtualCores\":0,\"availableVirtualCores\":7,\"allocatedVirtualCores\":1\"containersAllocated\":0,\"containersReserved\":0,\"containersPending\":0,\"totalMB\":17408\"totalVirtualCores\":8,\"totalNodes\":1,\"lostNodes\":0,\"unhealthyNodes\":0,\"decommissioningNodes\":0\"decommissionedNodes\":0,\"rebootedNodes\":0,\"activeNodes\":1,\"shutdownNodes\":0}}";
return strJsonStr;
}
/*********************
* Cluster Info API 요청
*********************/
public static String getYarnInfo() {
String strJsonStr = "{\"clusterInfo\":{\"id\":1324053971963,\"startedOn\":1324053971963\"state\":\"STARTED\",\"haState\":\"ACTIVE\",\"rmStateStoreName\":\"org.apache.hadoop.yarn.serverresourcemanager.recovery.NullRMStateStore\",\"resourceManagerVersion\":\"3.0.0-SNAPSHOT\"\"resourceManagerBuildVersion\":\"3.0.0-SNAPSHOT from unknown by user1 source checksum11111111111111111111111111111111\",\"resourceManagerVersionBuiltOn\":\"2016-01-01T01:00Z\"\"hadoopVersion\":\"3.0.0-SNAPSHOT\",\"hadoopBuildVersion\":\"3.0.0-SNAPSHOT from unknown by user1 sourcechecksum 11111111111111111111111111111111\",\"hadoopVersionBuiltOn\":\"2016-01-01T01:00Z\"\"haZooKeeperConnectionState\":\"ResourceManager HA is not enabled.\"}}";
return strJsonStr;
}
✅HomeController.java
// 테스트 컨트롤러
@RequestMapping(value = "/test", method = RequestMethod.GET)
public String test(Model model) {
logger.info("HomeController test start >>");
java.lang.reflect.Type mapType = new com.google.gson.reflect.TypeToken<Map<String, Object>>(){}.getType();
Gson gson = new Gson();
Map<String, Object> mapResult = new HashMap<String, Object>();
// Yarn Resource Manager API ROOT KEY (이부분은 JSON에 맞게 하드코딩)
String yarnResource[] = {"clusterMetrics", "clusterInfo"};
// API ROOT KEY 횟수 루프
for(int i=0; i<yarnResource.length; i++) {
// STEP1. API 요청후 JSON 얻기
String getYarnJson = BlangJsonUtil.getYarnData(yarnResource[i]); // JSON 문자열
System.out.println("■ API요청으로 받은 JSON 형태의 String: "+ getYarnJson);
// STEP2. 얻은 JSON 키값의 데이터타입별로 GSON 라이브러리로 Map<String, Object> 동적처리.
Map<String, Object> mapJson = gson.fromJson(getYarnJson, mapType);
System.out.println("■ API요청으로 받은 JSON 형태의 String 데이터를 객체로 파싱: " + mapJson);
// STEP3. ROOT KEY ACCESS
Map<String, Object> accessData = (Map<String, Object>) mapJson.get(yarnResource[i]);
System.out.println("■ 파싱한 데이터에서 JSON KEY 엑세스: " + accessData);
// STEP4. JS가 인식가능한 완벽한 JSON 문자열 생성
if (accessData != null) {
String resultData = BlangJsonUtil.mapToJson(accessData); // 완벽한 JSON 만들기
mapResult.put(yarnResource[i], resultData); //API 별로 MAP생성
System.out.println("■ 엑세스한 JSON 데이터의 키,값을 완벽한 JSON 문자열로 변경 " + accessData);
}
}
// 키값은 Yarn Resource Manager REST API 문서 참고
model.addAttribute("mapResult", mapResult);
return "jsp/test/BDP002023M00";
}
<script>
$(document).ready(function (){
/* Yarn Resource Manager REST API */
let jsonMetrics = '${mapResult.clusterMetrics}';
let jsonInfo = '${mapResult.clusterInfo}';
if (jsonMetrics != null) {
clusterMetrics = JSON.parse(jsonMetrics); //함수 성공조건: 완벽한 JSON 문자열이여야 함.
console.log(clusterMetrics.appsRunning);
}
if (jsonInfo != null) {
clusterInfo = JSON.parse(jsonInfo); //함수 성공조건: 완벽한 JSON 문자열이여야 함.
console.log(clusterInfo.state);
}
});
</script>
❗완전한 JSON 문자열처리 유틸(mapToJson) 사용시
💡 이렇게 JS에서 사용 가능한 TO-BE 형태로 변한다.Map<String, Object> mapResult = new HashMap<String, Object>(); String resultData = BlangJsonUtil.mapToJson("[파싱한 Map객체]"); mapResult.put("clusterMetrics", resultData);
/* 출력결과 AS-IS */ {clusterMetrics={"appsSubmitted":1.0,"appsCompleted":25000.0}} /* 출력결과 TO-BE*/ {clusterInfo={"appsSubmitted":"1.0","appsCompleted":"25000.0"}}
Leave a comment