따옴표 가 없 는 JSON 문자열 을 자바 가 수 동 으로 해석 하 는 작업

1 수요 설명
프로젝트 에서 따옴표 가 없 는 JSON 형식의 문자열 을 만 났 습 니 다.
{Name:Heal,Age:20,Tag:[Coding,Reading]}
JSON 대상 으로 해석 한 다음 Elasticsearch 에 삽입 하여 Object 형식의 대상 으로 저장 해 야 합 니 다.
알 리 의 FastJSon,Google 의 Gson 을 비교 해 보 니 원 하 는 기능 을 찾 지 못 했 습 니 다.😛), 그래서 스스로 도구 류 를 써 서 이 수 요 를 실현 했다.
따옴표 가 있 는 표준 JSON 문자열 이 라면 상기 2 가지 도 구 를 통 해 직접 분석 할 수 있 으 며 사용 방법 은 참고 할 수 있 습 니 다.
자바-JSON 문자열 을 포맷 하 는 두 가지 방식
2 분석 코드
2.1 사고의 실현
코드 의 주요 사고방식 은 주석 에 모두 설명 되 어 있 는데 주요 사고방식 은 다음 과 같다.
(1)Stack 통계 문자열 의 앞 뒤[],{}기호―[]대표 List,{}대표 Map;
(2)해 석 된 문자열 을 String\#subString()방법 으로 줄 이기;
(3)내부 의 List,Map 대상 을 재 귀적 으로 분석 합 니 다.
(4)처리 하기 편리 하도록 최소 key-value 는 모두 String 형식 으로 해석 합 니 다.
주의해 야 할 것 은 해석 할 문자열 내부 에 무의미 한{,},[,]기호 가 존재 하지 않 으 면 해석 에 이상 이 생 길 수 있 습 니 다.
-좋 은 호환성 방법 은 잠시 생각 하지 못 했 습 니 다.생각 있 는 동학 은 직접 메 시 지 를 남 겨 주세요.**
2.2 상세 코드

package com.healchow.util;

import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

/**
 * Java        JSON   
 *
 * @author Heal Chow
 * @date 2019/08/13 11:36
 */
public class ParseJsonStrUtils {

 public static void main(String[] args) {

  //        ,        key-value    ,            fastJson、Gson     
  //   : String          {、}、[、]   -            
  /*String sourceStr = "{\"_index\":\"book_shop\"," +
       "\"_id\":\"1\"," +
       "\"_source\":{" +
        "\"name\":\"Thinking in Java [4th Edition]\"," +
        "\"author\":\"[US] Bruce Eckel\"," +
        "\"price\":109.0,\"date\":\"2007-06-01 00:00:00\"," +
        "\"tags\":[\"Java\",[\"Programming\"]" +
       "}}";*/

  //         ,     []、{}     
  String sourceStr = "[[[{" +
       "{" +
        "Type:1," +
        "StoragePath:[{Name:/image/2019-08-01/15.jpeg,DeviceID:4401120000130},{ShotTime:2019-08-01 14:44:24}]," +
        "Width:140" +
       "}," +
       "{" +
        "Type:2,StoragePath:9090/pic/2019_08_01/src.jpeg," +
        "Inner:{DeviceID:44011200}," +
        "Test:[{ShotTime:2019-08-01 14:50:14}]," +
        "Width:5600}" +
       "}}]]]";

  List<Map<String, Object>> jsonArray;
  Map<String, Object> jsonMap;

  Object obj = null;
  try {
   obj = parseJson(sourceStr);
  } catch (Exception e) {
   System.out.println("   : " + e.getMessage());
   e.printStackTrace();
  }

  if (obj instanceof List) {
   jsonArray = (List<Map<String, Object>>) obj;
   System.out.println("     List  : " + jsonArray);
  } else if (obj instanceof Map) {
   jsonMap = (Map<String, Object>) obj;
   System.out.println("     Map  : " + jsonMap);
  } else {
   System.out.println("           JSON Array,     JSON Object!
: " + sourceStr); } } /** * Json , List Map * : (1) key value ",", key ":" ―― "," ":" * (2) JSON , , * "{a:b},{x:y}" ―― "[{a:b},{x:y}]" * @param sourceStr "[]" "{}" * @return JsonObject */ public static Object parseJson(String sourceStr) throws InvalidParameterException { if (sourceStr == null || "".equals(sourceStr)) { return sourceStr; } // 、 "[]" "{}" String parsedStr = simplifyStr(sourceStr, "[", "]"); parsedStr = simplifyStr(parsedStr, "{", "}"); // "[]" "{}" Stack<String> leftSymbolStack = new Stack<>(); Stack<String> rightSymbolStack = new Stack<>(); if ((parsedStr.startsWith("[") && parsedStr.endsWith("]")) || (parsedStr.startsWith("{") && parsedStr.endsWith("}"))) { leftSymbolStack.push(parsedStr.substring(0, 1)); rightSymbolStack.push(parsedStr.substring(parsedStr.length() - 1)); parsedStr = parsedStr.substring(1, parsedStr.length() - 1); // parsedStr "{{}}" parsedStr = simplifyStr(parsedStr, "{", "}"); } else { throw new InvalidParameterException(" '[]' '{}', !
: " + sourceStr); } // , jsonArray String, Map<String, Object> List<Object> jsonArray = new ArrayList<>(); Map<String, Object> jsonMap = new HashMap<>(16); // 、 innerParseByLoop(parsedStr, leftSymbolStack, rightSymbolStack, jsonArray, jsonMap); // jsonArray if (jsonArray.size() > 0) { return jsonArray; } else { return jsonMap; } } /** * List、Map */ private static void innerParseByLoop(String parsedStr, Stack<String> leftSymbolStack, Stack<String> rightSymbolStack, List<Object> jsonArray, Map<String, Object> jsonMap) throws InvalidParameterException { if (parsedStr == null || parsedStr.equals("")) { return; } // "," String[] allKeyValues = parsedStr.split(","); if (allKeyValues.length > 0) { // , ":" out: for (String keyValue : allKeyValues) { // keyValue ":", keyValue List<Map> , ":" ―― ":" int index = keyValue.indexOf(":"); if (index > 0) { // key "{" "[" , , String key = keyValue.substring(0, index); while (key.startsWith("[") || key.startsWith("{")) { leftSymbolStack.push(key.substring(0, 1)); // parsedStr = parsedStr.substring(1); key = key.substring(1); } // value "[" ―― List ―― String value = keyValue.substring(index + 1); if (value.startsWith("[")) { int innerIndex = parsedStr.indexOf("]"); List<Object> innerList = (List<Object>) parseJson(parsedStr.substring(key.length() + 1, innerIndex + 1)); jsonMap.put(key, innerList); // "]", "," parsedStr = parsedStr.substring(innerIndex + 1); if (parsedStr.indexOf(",") == 0) { parsedStr = parsedStr.substring(1); } // , "," , "," , innerParseByLoop(parsedStr, leftSymbolStack, rightSymbolStack, jsonArray, jsonMap); break; } // value "{" ―― Map ―― else if (value.startsWith("{")) { int innerIndex = parsedStr.indexOf("}"); Map<String, Object> innerMap = (Map<String, Object>) parseJson(parsedStr.substring(key.length() + 1, innerIndex + 1)); jsonMap.put(key, innerMap); // "}", "," parsedStr = parsedStr.substring(innerIndex + 1); if (parsedStr.indexOf(",") == 0) { parsedStr = parsedStr.substring(1); } // , "," , "," , innerParseByLoop(parsedStr, leftSymbolStack, rightSymbolStack, jsonArray, jsonMap); break; } // value "]" "}" else { while (value.endsWith("]") || value.endsWith("}")) { // String right = value.substring(value.length() - 1); // String top = leftSymbolStack.peek(); // , , if (("}".equals(right) && "{".equals(top)) || ("]".equals(right) && "[".equals(top))) { leftSymbolStack.pop(); value = value.substring(0, value.length() - 1); jsonMap.put(key, value); // "}", "," parsedStr = parsedStr.substring(key.length() + 1 + value.length() + 1); if (parsedStr.indexOf(",") == 0) { parsedStr = parsedStr.substring(1); } // , List , jsonArray.add(jsonMap); jsonMap = new HashMap<>(16); // continue out; } // , else { rightSymbolStack.push(right); value = value.substring(0, value.length() - 1); } } jsonMap.put(key, value); int length = key.length() + value.length() + 2; if (parsedStr.length() > length) { parsedStr = parsedStr.substring(length); } else { parsedStr = ""; } } } // keyValue ":", keyValue List<String> , List<Map> Map, List else { jsonArray.add(keyValue); } } // , ―― while (!leftSymbolStack.empty()) { if (leftSymbolStack.peek().equals("{") && parsedStr.equals("}")) { leftSymbolStack.pop(); } if (!rightSymbolStack.empty()) { if (leftSymbolStack.peek().equals("{") && rightSymbolStack.peek().equals("}")) { leftSymbolStack.pop(); rightSymbolStack.pop(); } else if (leftSymbolStack.peek().equals("[") && rightSymbolStack.peek().equals("]")) { leftSymbolStack.pop(); rightSymbolStack.pop(); } else { throw new InvalidParameterException(" JSON !
: " + parsedStr); } } } } } /** * 、 "[]" "{}", */ private static String simplifyStr(String sourceStr, String firstSymbol, String lastSymbol) { while (sourceStr.startsWith(firstSymbol) && sourceStr.endsWith(lastSymbol)) { String second = sourceStr.substring(1, 2); // "[" "{", "]" "}" ―― 3, IndexOutOfBoundsException if (second.equals(firstSymbol)) { String penultimate = sourceStr.substring(sourceStr.length() - 2, sourceStr.length() - 1); if (penultimate.equals(lastSymbol)) { // sourceStr = sourceStr.substring(1, sourceStr.length() - 1); } else { break; } } else { break; } } return sourceStr; } }
2.3 테스트 사례
(1)따옴표 가 있 는 테스트:

//      :
String sourceStr = "{\"_index\":\"book_shop\"," +
     "\"_id\":\"1\"," +
     "\"_source\":{" +
      "\"name\":\"Thinking in Java [4th Edition]\"," +
      "\"author\":\"[US] Bruce Eckel\"," +
      "\"price\":109.0,\"date\":\"2007-06-01 00:00:00\"," +
      "\"tags\":[\"Java\",[\"Programming\"]" +
     "}}";
분석 결과:

(2)따옴표 가 없 는 테스트:

//      : 
String sourceStr = "[[[{" +
     "{" +
      "Type:1," +
      "StoragePath:[{Name:/image/2019-08-01/15.jpeg,DeviceID:4401120000130},{ShotTime:2019-08-01 14:44:24}]," +
      "Width:140" +
     "}," +
     "{" +
      "Type:2,StoragePath:9090/pic/2019_08_01/src.jpeg," +
      "Inner:{DeviceID:44011200}," +
      "Test:[{ShotTime:2019-08-01 14:50:14}]," +
      "Width:5600}" +
     "}}]]]";
분석 결과:

추가 지식:키 이름 에 따옴표 가 없 는 JSON 문자열 을 JSON 대상 으로 변환 하 는 방법
4json.org위의 설명 에 따 르 면 JSON 대상 은 대상 구성원 으로 구성 되 고 구성원 은 key-value 키 로 구성 된다.
key 값 은 문자열 입 니 다:
문자열 은 유 니 코드 문자 로 구성 되 어 있 으 며,따옴표 로 둘러싸 고,역 슬 래 쉬 로 의 미 를 바 꿉 니 다.단일 문자 일 수 있 습 니 다.용법 은 C 나 자바 의 문자열 의 용법 과 비슷 하 다.
그러나 실제 애플 리 케 이 션 에 서 는 JSON 의 key 가 작은 따옴표 로 둘러싸 여야 한 다 는 것 을 아 는 프로그래머 가 별로 없다.대부분의 브 라 우 저 에 서 는 작은 따옴표 가 필요 하지 않 기 때문이다.그래서 왜 쓸데없는 짓 을 하면 두 개의 따옴표 를 더 써 야 합 니까?
규범 화 된 예:
{
"keyName" : 34
}
규범 에 맞지 않 는 예:
{
keyName : 34
}
브 라 우 저 에서 규범 에 맞지 않 고 더 블 따옴표 를 사용 하지 않 는 쓰기 가 브 라 우 저 에서 문제 가 되 지 않 지만 다른 곳 에서 문제 가 발생 하지 않 을 수 있다 는 것 은 아 닙 니 다.예 를 들 어 문자열 이 있 습 니 다.
//문자열 형식
'{ keyName : 34 }'
너 는 그것 을 JSON 대상 으로 바 꾸 고 싶다.JSON 문자열 을 JSON 대상 으로 변환 하려 면 JSON.parse()방법 을 사용 해 야 합 니 다.위의 키 이름 에 작은 따옴표 가 없 는 JSON 문자열 에 대해 서 는 JSON.parse()를 사용 하여 해석 할 때 오류 가 발생 하여 해석 할 수 없습니다.이것 은 매우 번 거 로 운 문제 가 되 었 다.그 러 니 가능 한 한 규범 적 인 예방 을 사용 하 는 것 이 좋다.비록 대부분 문제 가 없 지만.
그렇다면 키 이름 에 따옴표 가 없 는 JSON 문자열 에 대해 어떻게 JSON 대상 으로 변환 합 니까?
가장 직접적인 방법 은 키 이름 에 작은 따옴표 를 수 동 으로 붙 이 는 것 이다.
만약 당신 이 수 동 으로 추가 하지 않 는 다 면 함수 전문 검색 을 통 해 더 블 따옴표 를 추가 할 수 있 습 니 다.예 를 들 어 아래 의 이 코드 와 같 습 니 다.
json_string.replace(/(s*?{s*?|s*?,s*?)(['"])?([a-zA-Z0-9]+)(['"])?:/g, '$1"$3":');
eval('var json = new Object(' + json_string + ')');
마지막 으로 가장 간단 한 방법 은 eval()로 직접 실행 하 는 것 입 니 다.
var obj = eval('(' + invalid_json + ')');
그러나 이렇게 실행 할 때 실행 코드 가 무엇 인지 이해 해 야 한다.악성 프로그램 이 들 어 있다 면 이렇게 직접 실행 하면 안전 문 제 를 일 으 킬 수 있 기 때문이다.
이 자바 가 따옴표 가 없 는 JSON 문자열 을 수 동 으로 해석 하 는 작업 은 바로 작은 편집 이 여러분 에 게 공유 하 는 모든 내용 입 니 다.참고 하 시기 바 랍 니 다.많은 응원 부탁드립니다.

좋은 웹페이지 즐겨찾기