5

現在、ネストされたキーと値のペアなしでCamelにマップを返すJavaプロジェクトがあり、JacksonライブラリはJacksonライブラリを使用してJSONにうまくマーシャリングします。

たとえば、次の 2 つのキーと値を demoMap に入れるとします。

Map<String,String> demoMap = new TreeMap<String,String>
demoMap.put("key1","5");
demoMap.put("key2","10");

次の JSON を取得します。

{"key1":"5","key2":"10"}

ただし、一部のキー、値エントリには、マップにネストされたキー値として配置する必要があるオプションの可視性があります。オプションの可視性を持たないキーと値は、デフォルトを使用します。したがって、たとえば、key1 と key2 の可視性を指定し、key3 を指定しない場合、次のような JSON を取得したいと考えています。

{"key1":"5",
 "key2":"10",
 "key3":"17",
 "visibility" : { "key1": "a&b&!c", "key2": "a&b", "_default": "a" }
}

ネストされたキーと値のペアで Java オブジェクトをマーシャリングするように Camel を取得するにはどうすればよいですか? 私は視覚学習者なので、簡単な例が役に立ちます。

Map を変更して、値をオブジェクトとして持つようにしました。

Map<String,Object> demoMap = new TreeMap<String,Object>

そして、http: //examples.javacodegeeks.com/core-java/json/jackson/convert-java-map-to-from-json-using-jackson-exampleを使用して、ArrayListを使用していくつかのキーのネストされたキー、値を追加しようとしました/参照用ですが、これにより、ネストされたキーと値のペアの束ではなく、キーの下にネストされた値の束が得られることに気付きました。

笑って試してみても、Camel プロセッサからエラーが発生し、java.lang.ClassCastException で java.util.ArrayList を java.lang.String にキャストできないというエラーが発生しました。

同様に、demoMap 内に Map をネストしようとすると、次の ClassCastException が発生しました。

3244 [hello.world.request.timer] ERROR org.apache.camel.processor.DefaultErrorHandler  - Failed delivery for exchangeId: e6518e39-89b7-435e-96d9-ce26811ac67e. Exhausted after delivery attempt: 1 caught: java.lang.ClassCastException: java.util.HashMap cannot be cast to java.lang.String

だから私はそれをしない方法を知っています。:-/

http://camel.apache.org/json.htmlで Camel JSON ドキュメントを読み直しましたが、この記事の執筆時点では、ネストされたキーと値のペアを使用した例は指定されていません。

更新: Tom からのフィードバックに基づいて、2 つのマップを作成しました。

Map<String,String> keyvalues = new TreeMap<String,String>();
Map<String,String> visibility = new TreeMap<String,String>();

プロパティ ファイルを Map にロードする SensorGenerator と呼ぶクラスを次に示します。

package sample;

import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;

import org.codehaus.jackson.annotate.JsonAnyGetter;
import org.codehaus.jackson.annotate.JsonProperty;

public class SensorGenerator {

    private Properties sourceProperties;

    // create a map of sensor keyvalues, and a map of sensor visibility
    Map<String,String> keyvalues = new TreeMap<String,String>();
    @JsonProperty
    Map<String,String> visibility = new TreeMap<String,String>();

    @JsonAnyGetter
    public Map<String, String> getKeyvalues() { 

        for (Object key : sourceProperties.keySet()) {

            // Separate out each of the field:datatype:visibility tuples as an entry in the
            // values array
            String[] values = sourceProperties.getProperty((String) key).split(
                    ",");
            // split the key between 'sensor' and the 'number' Ex: sensor1 -> sensor,1
            String[] keyArray = key.toString().split("(?<=([a-zA-Z]++))");
            String keyNumber = keyArray[1]; // grab the number to append for each sensor

            // define string buffer that appends sensor number for each sensor's
            // keys.  Ex: sensor1 would have s1make, s1makeDataType, etc.
            StringBuffer sensorNumberStringBuffer = new StringBuffer();
            sensorNumberStringBuffer.append("s");
            sensorNumberStringBuffer.append(keyNumber);

            // make, its data type, and visibility (with s# prefix)
            StringBuffer makeStringBuffer = new StringBuffer();
            makeStringBuffer.append(sensorNumberStringBuffer);
            makeStringBuffer.append("make");
            StringBuffer makeDataTypeStringBuffer = new StringBuffer();
            makeDataTypeStringBuffer.append(sensorNumberStringBuffer);
            makeDataTypeStringBuffer.append("makeDataType");
            StringBuffer makeVizStringBuffer = new StringBuffer();
            makeVizStringBuffer.append(sensorNumberStringBuffer);
            makeVizStringBuffer.append("makeViz");

            // model, its data type, and visibility (with s# prefix)
            StringBuffer modelStringBuffer = new StringBuffer();
            modelStringBuffer.append(sensorNumberStringBuffer);
            modelStringBuffer.append("model");
            StringBuffer modelDataTypeStringBuffer = new StringBuffer();
            modelDataTypeStringBuffer.append(sensorNumberStringBuffer);
            modelDataTypeStringBuffer.append("modelDataType");
            StringBuffer modelVizStringBuffer = new StringBuffer();
            modelVizStringBuffer.append(sensorNumberStringBuffer);
            modelVizStringBuffer.append("modelViz");

            // serialNumber, its data type, and visibility (with s# prefix)
            StringBuffer serialNumberStringBuffer = new StringBuffer();
            serialNumberStringBuffer.append(sensorNumberStringBuffer);
            serialNumberStringBuffer.append("serialNumber");
            StringBuffer serialNumberDataTypeStringBuffer = new StringBuffer();
            serialNumberDataTypeStringBuffer.append(sensorNumberStringBuffer);
            serialNumberDataTypeStringBuffer.append("serialNumberDataType");
            StringBuffer serialNumberVizStringBuffer = new StringBuffer();
            serialNumberVizStringBuffer.append(sensorNumberStringBuffer);
            serialNumberVizStringBuffer.append("serialNumberViz");

            // sensorType, its data type, and visibility (with s# prefix)
            StringBuffer sensorTypeStringBuffer = new StringBuffer();
            sensorTypeStringBuffer.append(sensorNumberStringBuffer);
            sensorTypeStringBuffer.append("sensorType");
            StringBuffer sensorTypeDataTypeStringBuffer = new StringBuffer();
            sensorTypeDataTypeStringBuffer.append(sensorNumberStringBuffer);
            sensorTypeDataTypeStringBuffer.append("sensorTypeDataType");
            StringBuffer sensorTypeVizStringBuffer = new StringBuffer();
            sensorTypeVizStringBuffer.append(sensorNumberStringBuffer);
            sensorTypeVizStringBuffer.append("sensorTypeViz");

            //  put all the field:datatype keyvalues for this sensor in the keyvalues map
            //  and visibilities in the visibility map

            // make, data type, and visibility
            keyvalues.put(makeStringBuffer.toString(), values[0].split(":")[0]);
            keyvalues.put(makeDataTypeStringBuffer.toString(), values[0].split(":")[1]);
            visibility.put(makeVizStringBuffer.toString(), values[0].split(":")[2]);

            // model, data type, and visibility
            keyvalues.put(modelStringBuffer.toString(), values[1].split(":")[0]);
            keyvalues.put(modelDataTypeStringBuffer.toString(), values[1].split(":")[1]);
            visibility.put(modelVizStringBuffer.toString(), values[1].split(":")[2]);

            // serialNumber, data type, and visibility
            keyvalues.put(serialNumberStringBuffer.toString(), values[2].split(":")[0]);
            keyvalues.put(serialNumberDataTypeStringBuffer.toString(), values[2].split(":")[1]);
            visibility.put(serialNumberVizStringBuffer.toString(), values[2].split(":")[2]);

            // sensorType, data type, and visibility
            keyvalues.put(sensorTypeStringBuffer.toString(), values[3].split(":")[0]);
            keyvalues.put(sensorTypeDataTypeStringBuffer.toString(), values[3].split(":")[1]);
            visibility.put(sensorTypeVizStringBuffer.toString(), values[3].split(":")[2]);

            // add in default visibility
            visibility.put("_default", "a");

        }
        return keyvalues;
    }

    public void setSourceProperties(Properties properties) {
        this.sourceProperties = properties;
    }

}

現時点では、デフォルトの可視性を「a」にハードコードしただけですが、後でプロパティ ファイルから取得されるように変更する予定です。

4

1 に答える 1