source

JSON 형식을 모르는 Java에서의 JSON 해석

factcode 2023. 2. 13. 20:50
반응형

JSON 형식을 모르는 Java에서의 JSON 해석

JSON 문자열의 객체 구조를 알 수 없기 때문에 JSON 객체의 대략적인 구조를 알 수 있도록 Java에서 JSON 문자열을 해석하고 키와 값의 쌍을 찾으려고 합니다.

예를 들어, 하나의 실행에는 다음과 같은 JSON 문자열이 있을 수 있습니다.

  {"id" : 12345, "days" : [ "Monday", "Wednesday" ], "person" : { "firstName" : "David", "lastName" : "Menoyo" } }

그리고 이런 것도 있어요.

  {"url" : "http://someurl.com", "method" : "POST", "isauth" : false }

다양한 JSON 요소를 순환하여 키와 값을 판별하려면 어떻게 해야 합니까?나는 보았다jackson-core다음 토큰을 취득하여 토큰의 종류(필드명, 값, 어레이 시작 등)를 판별하는 방법은 알 수 있지만 실제 토큰의 값을 취득하는 방법은 알 수 없습니다.

예를 들어 다음과 같습니다.

public void parse(String json)  {
  try {
     JsonFactory f = new JsonFactory();
     JsonParser parser = f.createParser(json);
     JsonToken token = parser.nextToken();
     while (token != null) {
        if (token.equals(JsonToken.START_ARRAY)) {
           logger.debug("Start Array : " + token.toString());
        } else if (token.equals(JsonToken.END_ARRAY)) {
           logger.debug("End Array : " + token.toString());
        } else if (token.equals(JsonToken.START_OBJECT)) {
           logger.debug("Start Object : " + token.toString());
        } else if (token.equals(JsonToken.END_OBJECT)) {
           logger.debug("End Object : " + token.toString());
        } else if (token.equals(JsonToken.FIELD_NAME)) {
           logger.debug("Field Name : " + token.toString());
        } else if (token.equals(JsonToken.VALUE_FALSE)) {
           logger.debug("Value False : " + token.toString());
        } else if (token.equals(JsonToken.VALUE_NULL)) {
           logger.debug("Value Null : " + token.toString());
        } else if (token.equals(JsonToken.VALUE_NUMBER_FLOAT)) {
           logger.debug("Value Number Float : " + token.toString());
        } else if (token.equals(JsonToken.VALUE_NUMBER_INT)) {
          logger.debug("Value Number Int : " + token.toString());
        } else if (token.equals(JsonToken.VALUE_STRING)) {
           logger.debug("Value String : " + token.toString());
        } else if (token.equals(JsonToken.VALUE_TRUE)) {
           logger.debug("Value True : " + token.toString());
        } else {
           logger.debug("Something else : " + token.toString());
        }
        token = parser.nextToken();
     }
  } catch (Exception e) {
     logger.error("", e);
  }
}

에 클래스가 있나요?jackson또는 다른 라이브러리(gson또는simple-json트리를 생성하거나 json 요소를 순환하여 값과 더불어 실제 키 이름을 얻을 수 있도록 합니다.

Jacksons의 내장 트리 모델 기능을 소개합니다.

암호는 다음과 같습니다.

public void parse(String json)  {
       JsonFactory factory = new JsonFactory();

       ObjectMapper mapper = new ObjectMapper(factory);
       JsonNode rootNode = mapper.readTree(json);  

       Iterator<Map.Entry<String,JsonNode>> fieldsIterator = rootNode.fields();
       while (fieldsIterator.hasNext()) {

           Map.Entry<String,JsonNode> field = fieldsIterator.next();
           System.out.println("Key: " + field.getKey() + "\tValue:" + field.getValue());
       }
}

다른 라이브러리로 괜찮다면 org.json을 사용해 보십시오.

JSONObject object = new JSONObject(myJSONString);
String[] keys = JSONObject.getNames(object);

for (String key : keys)
{
    Object value = object.get(key);
    // Determine type of value and do something with it...
}

Gson 라이브러리를 사용하여 알 수 없는 Json 개체를 구문 분석할 수 있는 다음 코드를 찾습니다.

public class JsonParsing {
static JsonParser parser = new JsonParser();

public static HashMap<String, Object> createHashMapFromJsonString(String json) {

    JsonObject object = (JsonObject) parser.parse(json);
    Set<Map.Entry<String, JsonElement>> set = object.entrySet();
    Iterator<Map.Entry<String, JsonElement>> iterator = set.iterator();
    HashMap<String, Object> map = new HashMap<String, Object>();

    while (iterator.hasNext()) {

        Map.Entry<String, JsonElement> entry = iterator.next();
        String key = entry.getKey();
        JsonElement value = entry.getValue();

        if (null != value) {
            if (!value.isJsonPrimitive()) {
                if (value.isJsonObject()) {

                    map.put(key, createHashMapFromJsonString(value.toString()));
                } else if (value.isJsonArray() && value.toString().contains(":")) {

                    List<HashMap<String, Object>> list = new ArrayList<>();
                    JsonArray array = value.getAsJsonArray();
                    if (null != array) {
                        for (JsonElement element : array) {
                            list.add(createHashMapFromJsonString(element.toString()));
                        }
                        map.put(key, list);
                    }
                } else if (value.isJsonArray() && !value.toString().contains(":")) {
                    map.put(key, value.getAsJsonArray());
                }
            } else {
                map.put(key, value.getAsString());
            }
        }
    }
    return map;
}
}

해시맵에 알 수 없는 형식의 JSON

JSON을 쓰고 JSON을 읽습니다.

public static JsonParser parser = new JsonParser();
public static void main(String args[]) {
     writeJson("JsonFile.json");
     readgson("JsonFile.json");
}
public static void readgson(String file) {
    try {
        System.out.println( "Reading JSON file from Java program" );

        FileReader fileReader = new FileReader( file );
        com.google.gson.JsonObject object = (JsonObject) parser.parse( fileReader );

        Set <java.util.Map.Entry<String, com.google.gson.JsonElement>> keys = object.entrySet();
        if ( keys.isEmpty() ) {
            System.out.println( "Empty JSON Object" );
        }else {
            Map<String, Object> map = json_UnKnown_Format( keys );
            System.out.println("Json 2 Map : "+map);
        }

    } catch (IOException ex) {
        System.out.println("Input File Does not Exists.");
    }
}
public static Map<String, Object> json_UnKnown_Format( Set <java.util.Map.Entry<String, com.google.gson.JsonElement>> keys ){
    Map<String, Object> jsonMap = new HashMap<String, Object>();
    for (Entry<String, JsonElement> entry : keys) {
        String keyEntry = entry.getKey();
        System.out.println(keyEntry + " : ");
        JsonElement valuesEntry =  entry.getValue();
        if (valuesEntry.isJsonNull()) {
            System.out.println(valuesEntry);
            jsonMap.put(keyEntry, valuesEntry);
        }else if (valuesEntry.isJsonPrimitive()) {
            System.out.println("P - "+valuesEntry);
            jsonMap.put(keyEntry, valuesEntry);
        }else if (valuesEntry.isJsonArray()) {
            JsonArray array = valuesEntry.getAsJsonArray();
            List<Object> array2List = new ArrayList<Object>();
            for (JsonElement jsonElements : array) {
                System.out.println("A - "+jsonElements);
                array2List.add(jsonElements);
            }
            jsonMap.put(keyEntry, array2List);
        }else if (valuesEntry.isJsonObject()) {             
             com.google.gson.JsonObject obj = (JsonObject) parser.parse(valuesEntry.toString());                    
             Set <java.util.Map.Entry<String, com.google.gson.JsonElement>> obj_key = obj.entrySet();
             jsonMap.put(keyEntry, json_UnKnown_Format(obj_key));
        }
    }
    return jsonMap;
}
@SuppressWarnings("unchecked")
public static void writeJson( String file ) {

    JSONObject json = new JSONObject();

    json.put("Key1", "Value");
    json.put("Key2", 777); // Converts to "777"
    json.put("Key3", null);
    json.put("Key4", false);

        JSONArray jsonArray = new JSONArray();
        jsonArray.put("Array-Value1");
        jsonArray.put(10); 
        jsonArray.put("Array-Value2");

    json.put("Array : ", jsonArray); // "Array":["Array-Value1", 10,"Array-Value2"]

        JSONObject jsonObj = new JSONObject();
        jsonObj.put("Obj-Key1", 20);
        jsonObj.put("Obj-Key2", "Value2");
        jsonObj.put(4, "Value2"); // Converts to "4"

    json.put("InnerObject", jsonObj);

        JSONObject jsonObjArray = new JSONObject();
            JSONArray objArray = new JSONArray();
            objArray.put("Obj-Array1");
            objArray.put(0, "Obj-Array3");
        jsonObjArray.put("ObjectArray", objArray);

    json.put("InnerObjectArray", jsonObjArray);

        Map<String, Integer> sortedTree = new TreeMap<String, Integer>();
        sortedTree.put("Sorted1", 10);
        sortedTree.put("Sorted2", 103);
        sortedTree.put("Sorted3", 14);

    json.put("TreeMap", sortedTree);        

    try {
        System.out.println("Writting JSON into file ...");
        System.out.println(json);
        FileWriter jsonFileWriter = new FileWriter(file);
        jsonFileWriter.write(json.toJSONString());
        jsonFileWriter.flush();
        jsonFileWriter.close();
        System.out.println("Done");

    } catch (IOException e) { 
        e.printStackTrace();
    }

}

다음은 json을 해석하고 그 안에 있는 모든 숫자를 엉망으로 만드는 방법을 나타낸 샘플입니다.

public class JsonParser {

    public static Object parseAndMess(Object object) throws IOException {
        String json = JsonUtil.toJson(object);
        JsonNode jsonNode = parseAndMess(json);
        if(null != jsonNode)
            return JsonUtil.toObject(jsonNode, object.getClass());

        return null;
    }

    public static JsonNode parseAndMess(String json) throws IOException {
        JsonNode rootNode = parse(json);
        return mess(rootNode, new Random());
    }

    private static JsonNode parse(String json) throws IOException {
        JsonFactory factory = new JsonFactory();
        ObjectMapper mapper = new ObjectMapper(factory);
        JsonNode rootNode = mapper.readTree(json);
        return rootNode;

    }

    private static JsonNode mess(JsonNode rootNode, Random rand) throws IOException {
        if (rootNode instanceof ObjectNode) {
            Iterator<Map.Entry<String, JsonNode>> fieldsIterator = rootNode.fields();
            while (fieldsIterator.hasNext()) {
                Map.Entry<String, JsonNode> field = fieldsIterator.next();
                replaceObjectNode((ObjectNode) rootNode, field, rand);
            }
        } else if (rootNode instanceof ArrayNode) {
            ArrayNode arrayNode = ((ArrayNode) rootNode);
            replaceArrayNode(arrayNode, rand);
        }
        return rootNode;
    }

    private static void replaceObjectNode(ObjectNode rootNode, Map.Entry<String, JsonNode> field, Random rand)
            throws IOException {
        JsonNode childNode = field.getValue();
        if (childNode instanceof IntNode) {
            (rootNode).put(field.getKey(), rand.nextInt(1000));
        } else if (childNode instanceof LongNode) {
            (rootNode).put(field.getKey(), rand.nextInt(1000000));
        } else if (childNode instanceof FloatNode) {
            (rootNode).put(field.getKey(), format(rand.nextFloat()));
        } else if (childNode instanceof DoubleNode) {
            (rootNode).put(field.getKey(), format(rand.nextFloat()));
        } else {
            mess(childNode, rand);
        }
    }

    private static void replaceArrayNode(ArrayNode arrayNode, Random rand) throws IOException {
        int arrayLength = arrayNode.size();
        if(arrayLength == 0)
            return;
        if (arrayNode.get(0) instanceof IntNode) {
            for (int i = 0; i < arrayLength; i++) {
                arrayNode.set(i, new IntNode(rand.nextInt(10000)));
            }
        } else if (arrayNode.get(0) instanceof LongNode) {
            arrayNode.removeAll();
            for (int i = 0; i < arrayLength; i++) {
                arrayNode.add(rand.nextInt(1000000));
            }
        } else if (arrayNode.get(0) instanceof FloatNode) {
            arrayNode.removeAll();
            for (int i = 0; i < arrayLength; i++) {
                arrayNode.add(format(rand.nextFloat()));
            }
        } else if (arrayNode.get(0) instanceof DoubleNode) {
            arrayNode.removeAll();
            for (int i = 0; i < arrayLength; i++) {
                arrayNode.add(format(rand.nextFloat()));
            }
        } else {
            for (int i = 0; i < arrayLength; i++) {
                mess(arrayNode.get(i), rand);
            }
        }
    }

    public static void print(JsonNode rootNode) throws IOException {
        System.out.println(rootNode.toString());
    }

    private static double format(float a) {
        return Math.round(a * 10000.0) / 100.0;
    }
}

다음 항목에 만족하십니까?Map잭슨한테요?

ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> map = objectMapper.readValue(jsonString, new TypeReference<HashMap<String,Object>>(){});

아니면...JsonNode?

JsonNode jsonNode = objectMapper.readTree(String jsonString) 

언급URL : https://stackoverflow.com/questions/19760138/parsing-json-in-java-without-knowing-json-format

반응형