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
の- JsonParser
を見ました。次の「トークン」を取得し、トークンの種類(フィールド名、値、配列の開始など)を判断する方法はわかりますが、実際のトークンの値を取得する方法はわかりません。
例えば:
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ライブラリを使用したUnknown Json Object解析の次のコードを見つけます。
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;
}
}
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をJavaオブジェクト(マップ)にすばやく取り込み、「ドリル」して操作できるようにするには、json-io( https://github.com/jdereg/json- io )。このライブラリを使用すると、JSON文字列を読み取って、「Map of Maps」表現を取得できます。
JVMに対応するJavaクラスがある場合、JSONを読み取ることができ、JSONをJavaクラスのインスタンスに直接解析します。
JsonReader.jsonToMaps(String json)
ここで、jsonは読み取るJSONを含む文字列です。戻り値は、キーにJSONフィールドが含まれるマップであり、値には関連する値が含まれます。
JsonReader.jsonToJava(String json)
は同じJSON文字列を読み取り、戻り値はJSONにシリアル化されたJavaインスタンスになります。 JVMに記述されたクラスがある場合、このAPIを使用します
JsonWriter.objectToJson(MyClass foo).
ジャクソンのMap
に満足しますか?
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> map = objectMapper.readValue(jsonString, new TypeReference<HashMap<String,Object>>(){});
それともJsonNode
?
JsonNode jsonNode = objectMapper.readTree(String jsonString)
私が書いたサンプルは、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;
}
}