9

javaを使用してJSONオブジェクトのリストをHashMapに変換するために組み込みのJackson機能を使用する方法はありますか

説明: 解析する必要がある Json 構造

{
    list:[
        {
            keyId : 1,
            keyLabel : "Test 1",
            valueId: 34,
            valueLabel: "Test Lable"
        },
        {
            keyId : 2,
            keyLabel : "Test 2",
            valueId: 35,
            valueLabel: "Test Lable"
        },
        {
            keyId : 3,
            keyLabel : "Test 3",
            valueId: 36,
            valueLabel: "Test Lable"
        }
    ]
}

私が期待しているオブジェクトモデルは、

class Key{
    int keyId;
    String keyLable;

    hashCode(){
    return keyId.hashCode();
    }
}

class Value{
    int valueId;
    String valueLable;

    hashCode(){
    return valueId.hashCode();
    }
}

上記の json リストを次のようなマップに変換する必要があります。

HashMap<Key,Value> map;
4

4 に答える 4

1

手動で行うことをお勧めします。数行書くだけです。何かのようなもの

    ObjectMapper jmap = new ObjectMapper();
    //Ignore value properties
    List<Key> keys = jmap.readValue("[{}, {}]", jmap.getTypeFactory().constructCollectionType(ArrayList.class, Key.class));
    //Ignore key properties
    List<Value> values = jmap.readValue("[{}, {}]", jmap.getTypeFactory().constructCollectionType(ArrayList.class, Value.class));

    Map<Key, Value> data = new HashMap<>();
    for (int i = 0; i < keys.size(); i++) {
        data.put(keys.get(i), values.get(i));
    }

注: json とモデルにスペルの不一致があります (valueLabel != valueLable)。

于 2016-03-04T06:01:02.143 に答える
0

この答えはあなたが探しているものではないかもしれません。確かに単純な解決策ではありません。このヘルパー クラスは、DOM-XML パーサーとは異なり、SAX-XML パーサーのように入力ファイルを読み取ります。

私のユースケースは、大規模な「ランダムに」構造化された json ファイルと更新データベース オブジェクトです。これにより、ドキュメント全体が RAM メモリに読み込まれることはありません。厳密に型指定されたオブジェクトを使用できないため、ハッシュマップ ソリューションを使用しました。

これは、入力ファイルをループし、指定されたブレークポイント オブジェクト パスごとにフィールド値を収集し、ハンドラー関数を呼び出します。Hashmap にはparent.entry.field=xxxxx値があり、keyval ペアをダンプして命名構文を確認します。

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Stack;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;

public class JSONHandler {
    private Stack<String> parents;
    private String cachedParent;
    private Map<String,String> entry;
    private Map<String,String> parentEntry;

    public JSONHandler(JSONHandler.EntryHandler handler, JsonParser jsonP, 
                        String path) throws Exception {
        parents = new Stack<String>();
        entry = new LinkedHashMap<String,String>(16);// new HashMap<String,String>(16);
        parentEntry = new LinkedHashMap<String,String>(8);

        if (!path.endsWith(".")) path+=".";

        boolean isParent=true;
        int arrayIdx=-1;
        cachedParent="";
        JsonToken token;
        boolean doProcess=true;
        while ( (token=jsonP.nextToken()) != null) {
            String name = jsonP.getCurrentName();
            if (token == JsonToken.START_OBJECT) {
                parents.push(name);
                if (cachedParent.equals(path)) {
                    entry.clear(); // start new target entry
                    arrayIdx=0;
                    if (!parentEntry.isEmpty()) entry.putAll(parentEntry);
                    isParent=false;
                } else if (!cachedParent.startsWith(path)) {
                    isParent=true; // add fields to parent entry
                }
                cachedParent = implodeStack(parents);
            } else if (token == JsonToken.END_OBJECT) {
                parents.pop();
                cachedParent = implodeStack(parents);
                if (cachedParent.equals(path)) {
                    doProcess=handler.process(entry);
                    arrayIdx=-1;
                    if (!doProcess) break;
                } else if (name==null && cachedParent.startsWith(path)) {
                    String sArrayIdx = parents.peek(); // increment arrayIndex+1
                    parents.set(parents.size()-1, ""+(Integer.parseInt(sArrayIdx)+1) );
                    cachedParent = implodeStack(parents);
                } else if (!cachedParent.startsWith(path)) {
                    Iterator<Map.Entry<String,String>> iter=parentEntry.entrySet().iterator();
                    while(iter.hasNext()) {
                        Map.Entry<String,String> me = iter.next();
                        if (me.getKey().startsWith(cachedParent))
                            iter.remove();
                    }
                }
            } else if (token == JsonToken.START_ARRAY) {
                parents.push(name);
                if (arrayIdx>-1) parents.push(String.valueOf(arrayIdx));
                cachedParent = implodeStack(parents);
            } else if (token == JsonToken.END_ARRAY) {
                parents.pop();
                if (arrayIdx>-1) {
                    parents.pop();
                    arrayIdx=0;
                }
                cachedParent = implodeStack(parents);
            } else if (token == JsonToken.FIELD_NAME) {
                //System.out.println("field="+jsonP.getCurrentName());
            } else {
                String value;
                if (token == JsonToken.VALUE_NULL) value = null;
                else if (token == JsonToken.VALUE_TRUE) value = "1";
                else if (token == JsonToken.VALUE_FALSE) value = "0";
                else value = jsonP.getText();
                if (cachedParent.startsWith(path)) {
                    if (name==null && arrayIdx>-1) {
                        // simple array "values":["aa","bb","cc"], 
                        // write parent.item.values.0=aa, .1=bb, .2=cc
                        parents.set(parents.size()-1, ""+(arrayIdx++) );
                        cachedParent = implodeStack(parents);
                        entry.put(cachedParent.substring(0,cachedParent.length()-1), value);
                    } else
                        entry.put(cachedParent+name, value);
                } else if (isParent) {
                    parentEntry.put(cachedParent+name, value);
                }
            }
        }
    }

    private String implodeStack(Stack<String> stack) {
        StringBuilder sb = new StringBuilder();
        for(String value : stack) {
            if (value!=null)
                sb.append(value + ".");
        }
        return sb.toString();
    }


    public static interface EntryHandler {
        public void startDocument() throws Exception;
        public boolean process(Map<String,String> entry) throws Exception;
    }

}

クライアント例

    JSONHandler.EntryHandler handler = new JSONHandler.EntryHandler() {
        public void startDocument() throws Exception {};
        public boolean process(Map<String,String> entry) throws Exception {
            for(String key : entry.keySet())
                System.out.println(key+"="+entry.get(key));
            return true;
        }
    };

    JsonFactory jsonF = new JsonFactory();
    jsonF.enable(JsonParser.Feature.AUTO_CLOSE_SOURCE);
    JsonParser jsonP = jsonF.createParser(file);
    try {
       handler.startDocument();
       new JSONHandler(handler, jsonP, "list");
    } finally {
       jsonP.close();
    }

(私のアプリケーションからの単純化をコピーペーストすると、構文エラーが発生する可能性があります)

于 2016-03-04T14:44:50.747 に答える
0

最初にリストをマップの配列に変換してから、キーと値のマップを作成します。

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonMapExample {

    public static void main(String[] args) {

        try {

            ObjectMapper mapper = new ObjectMapper();
            String json = "{\"list\":[{\"keyId\":1,\"keyLabel\":\"Test 1\",\"valueId\":34,\"valueLabel\":\"Test Lable\"},{\"keyId\":2,\"keyLabel\":\"Test 2\",\"valueId\":35,\"valueLabel\":\"Test Lable\"},{\"keyId\":3,\"keyLabel\":\"Test 3\",\"valueId\":36,\"valueLabel\":\"Test Lable\"}]}";
            JsonNode node = mapper.readTree(json).path("list");
            JsonParser parser = mapper.treeAsTokens(node);
            Map<String, Object>[] clients = parser.readValueAs(new TypeReference<Map<String, Object>[]>() {
            });
            Map<Key, Value> result = new HashMap<Key, Value>();
            for (Map<String, Object> map : clients) {
                int keyId = Integer.parseInt(map.get("keyId").toString());
                int valueId = Integer.parseInt(map.get("valueId").toString());
                result.put(new Key(keyId, map.get("keyLabel").toString()),
                        new Value(valueId, map.get("valueLabel").toString()));
            }
            System.out.println(result);
        } catch (JsonGenerationException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
于 2016-03-04T06:13:01.887 に答える