Ich versuche, JSON-Zeichenfolgen in Java zu analysieren und die Schlüssel-Wert-Paare zu finden, damit ich die ungefähre Struktur des JSON-Objekts ermitteln kann, da die Objektstruktur der JSON-Zeichenfolge unbekannt ist.
Eine Ausführung kann beispielsweise eine JSON-Zeichenfolge wie folgt enthalten:
{"id" : 12345, "days" : [ "Monday", "Wednesday" ], "person" : { "firstName" : "David", "lastName" : "Menoyo" } }
Und noch eines davon:
{"url" : "http://someurl.com", "method" : "POST", "isauth" : false }
Wie gehe ich durch die verschiedenen JSON-Elemente und bestimme die Schlüssel und ihre Werte? Ich habe mir jackson-core
s JsonParser
angesehen. Ich sehe, wie ich das nächste "Token" packen kann und feststellen kann, um welche Art von Token es sich handelt (d. H. Feldname, Wert, Array-Start usw.), aber ich weiß nicht, wie ich den tatsächlichen Wert des Tokens ermitteln kann.
Zum Beispiel:
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);
}
}
Gibt es eine Klasse in jackson
oder einer anderen Bibliothek (gson
oder simple-json
), die einen Baum erzeugt oder die Json-Elemente durchlaufen lässt und zusätzlich zu den Werten die tatsächlichen Schlüsselnamen abruft?
Schauen Sie sich die integrierte Baummodellfunktion von Jacksons an.
Und dein Code wird sein:
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());
}
}
Wenn eine andere Bibliothek für Sie in Ordnung ist, können Sie org.json versuchen:
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...
}
Suchen Sie den folgenden Code für die Analyse von unbekannten Json-Objekten mithilfe der Gson-Bibliothek.
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 unbekanntes Format in HashMap
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();
}
}
Um JSON schnell in Java-Objekte (Maps) zu importieren, mit denen Sie anschließend "bohren" und damit arbeiten können, können Sie json-io verwenden ( https://github.com/jdereg/json-io ). In dieser Bibliothek können Sie einen JSON-String lesen und eine 'Map of Maps'-Darstellung erhalten.
Wenn Sie über die entsprechenden Java-Klassen in Ihrer JVM verfügen, können Sie den JSON-Code lesen und ihn direkt in Instanzen der Java-Klassen parsen.
JsonReader.jsonToMaps(String json)
dabei ist Json der String, der den zu lesenden JSON enthält. Der Rückgabewert ist eine Map, in der die Schlüssel die JSON-Felder und die Werte die zugehörigen Werte enthalten.
JsonReader.jsonToJava(String json)
liest den gleichen JSON-String ein und der Rückgabewert ist die Java-Instanz, die in JSON serialisiert wurde. Verwenden Sie diese API, wenn sich in Ihrer JVM Klassen befinden, die von geschrieben wurden
JsonWriter.objectToJson(MyClass foo).
Würdest du mit einem Map
von Jackson zufrieden sein?
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> map = objectMapper.readValue(jsonString, new TypeReference<HashMap<String,Object>>(){});
Oder vielleicht ein JsonNode
?
JsonNode jsonNode = objectMapper.readTree(String jsonString)
Hier ist ein Beispiel, das ich geschrieben habe, zeigt, wie ich einen Json analysiere und jede Zahl darin verwirre:
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;
}
}