2017-02-07 6 views
0

を含むオブジェクトをシリアル化するために、私は入力のparamsすなわち(コンテンツのバージョン、コンテンツIDのリスト)に基づいて動的にJSONを次生成しようとしていますのJava +ジャクソン:どのように他のオブジェクトの配列/リスト

{ 
    "query": { 
    "bool": { 
     "must": [ 
     { 
      "term": { 
      "version": { 
       "value": "published" 
      } 
      } 
     }, 
     { 
      "terms": { 
      "contentId": [ 
      "contentId-123", 
      "contentId-456" 
      ] 
      } 
     } 
     ] 
    } 
    } 
} 

上記のjsonは、弾性検索削除要求の照会本体です。上述のjsonに記載されている versionおよびcontentIdは、コンテンツオブジェクトまたはデータモデルの実際のフィールド/属性です。

オブジェクトをシリアライズしながら、私はこの例外を取得しています:ここで

com.fasterxml.jackson.core.JsonGenerationException: Can not start an object, expecting field name 
    at com.fasterxml.jackson.core.JsonGenerator._reportError(JsonGenerator.java:1886) 
    at com.fasterxml.jackson.core.json.WriterBasedJsonGenerator._verifyPrettyValueWrite(WriterBasedJsonGenerator.java:832) 
    at com.fasterxml.jackson.core.json.WriterBasedJsonGenerator._verifyValueWrite(WriterBasedJsonGenerator.java:797) 
    at com.fasterxml.jackson.core.json.WriterBasedJsonGenerator.writeStartObject(WriterBasedJsonGenerator.java:268) 
    at com.cdk.dmg.services.sitecontent.util.ConstantsTest$DeleteQuerySerializer.serialize(Test.java:200) 
    at com.cdk.dmg.services.sitecontent.util.ConstantsTest$DeleteQuerySerializer.serialize(Test.java:183) 
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:292) 
    at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1419) 
    at com.fasterxml.jackson.databind.ObjectWriter._configAndWriteValue(ObjectWriter.java:1147) 
    at com.fasterxml.jackson.databind.ObjectWriter.writeValueAsString(ObjectWriter.java:1020) 

は私のコードです:

class SearchParam { 
    boolean isMultivalued; 
    String fieldName; 
    String value; 
    List<String> values; 

    @Override 
    public String toString() { 
     final StringBuilder sb = new StringBuilder("SearchParam{"); 
     sb.append("isMultivalued=").append(isMultivalued); 
     sb.append(", fieldName='").append(fieldName).append('\''); 
     sb.append(", value='").append(value).append('\''); 
     sb.append(", values=").append(values); 
     sb.append('}'); 
     return sb.toString(); 
    } 
} 

class DeleteQuery { 
    List<SearchParam> mustParams; 
} 

class DeleteQuerySerializer extends StdSerializer<DeleteQuery> { 

    protected DeleteQuerySerializer(Class<DeleteQuery> t) { 
     super(t); 
    } 

    public DeleteQuerySerializer() { 
     this(null); 
    } 

    @Override 
    public void serialize(DeleteQuery value, JsonGenerator jsonGen, SerializerProvider provider) throws IOException { 
     jsonGen.writeStartObject(); 
     jsonGen.writeObjectFieldStart("query"); 
     jsonGen.writeObjectFieldStart("bool"); 
     jsonGen.writeArrayFieldStart("must"); 
     for (SearchParam param : value.mustParams) { 
      jsonGen.writeObject(param); 
     } 
     jsonGen.writeEndObject(); 
    } 
} 

class SearchParamSerializer extends StdSerializer<SearchParam> { 

    protected SearchParamSerializer(Class<SearchParam> t) { 
     super(t); 
    } 

    protected SearchParamSerializer() { 
     this(null); 
    } 

    @Override 
    public void serialize(SearchParam value, JsonGenerator jsonGen, SerializerProvider provider) throws IOException, JsonGenerationException { 
     jsonGen.writeStartObject(); 
     if (value.isMultivalued) { 
      jsonGen.writeObjectFieldStart("terms"); 
      jsonGen.writeArrayFieldStart(value.fieldName); 
      for (String v : value.values) { 
       jsonGen.writeString(v); 
      } 
      jsonGen.writeEndArray(); 
     } else { 
      jsonGen.writeObjectFieldStart("term"); 
      jsonGen.writeObjectFieldStart(value.fieldName); 
      jsonGen.writeStringField("value", value.value); 
     } 
     jsonGen.writeEndObject(); 
    } 
} 

@Test 
public void dummyTest() throws JsonProcessingException { 

    SearchParam versionParam = new SearchParam(); 
    versionParam.fieldName = "version"; 
    versionParam.isMultivalued = false; 
    versionParam.value = "published"; 

    SearchParam idParam = new SearchParam(); 
    idParam.fieldName = "contentId"; 
    idParam.isMultivalued = true; 
    idParam.values = Arrays.asList("contentID-1", "contentID-2", "contentID-3"); 

    List<SearchParam> mustParams = Arrays.asList(versionParam, idParam); 

    ObjectMapper mapper = new ObjectMapper(); 

    SimpleModule module = new SimpleModule(); 
    module.addSerializer(SearchParam.class, new SearchParamSerializer()); 
    module.addSerializer(DeleteQuery.class, new DeleteQuerySerializer()); 
    mapper.registerModule(module); 

    DeleteQuery deleteQuery = new DeleteQuery(); 
    deleteQuery.mustParams = mustParams; 

    String serialized = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(deleteQuery); 
    System.out.println(serialized); 
} 

参考: jackson-custom-serialization

私はコードに少しの調整をしました(たとえば、 SearchParamSerializer.serialize()の内部には012についてはjsonGen.writeStartObject()jsonGen.writeEndObject()が再配置されています条件)、期待どおりの結果が得られません。

グーグルとスタックオーバーフローが多発していますが、私はリンクがほとんどありませんが、GsonライブラリやPythonで詳しく説明しています。

助けてください!

答えて

0

ところで、あなたはこのAPIを見ましたか?https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/index.html

+0

はい。しかし、我々は弾性検索のJava APIに基づいた別のプロジェクトを持っており、それを利用しなければなりません。私は、QueryBuilderのelasticのJava APIを直接使用することはできません。さらに、その異なるプロジェクトは私のチームの範囲を超えています。 – manoj

+0

私はあなたのコードを見ています。 –

0

私の回避策を今すぐ進めてください。

次のようにDeleteQueryDeleteQuerySerializerを更新:

class DeleteQuery { 
    List<String> mustParams; 
} 

class DeleteQuerySerializer extends StdSerializer<DeleteQuery> { 

    protected DeleteQuerySerializer(Class<DeleteQuery> t) { 
     super(t); 
    } 

    public DeleteQuerySerializer() { 
     this(null); 
    } 

    @Override 
    public void serialize(DeleteQuery value, JsonGenerator jsonGen, SerializerProvider provider) throws IOException { 
     jsonGen.writeStartObject(); 
     jsonGen.writeObjectFieldStart("query"); 
     jsonGen.writeObjectFieldStart("bool"); 
     String mustParam = String.join(",", value.mustParams); 
     jsonGen.writeFieldName("must"); 
     jsonGen.writeRawValue("[" + mustParam + "]"); 
     jsonGen.writeEndObject(); 
    } 
} 

そして、ここではdummyTest()次のとおりです。

public void dummyTest() throws IOException { 
    System.out.println(); 

    SearchParam versionParam = new SearchParam(); 
    versionParam.fieldName = "version"; 
    versionParam.isMultivalued = false; 
    versionParam.value = "published"; 

    SearchParam idParam = new SearchParam(); 
    idParam.fieldName = "contentId"; 
    idParam.isMultivalued = true; 
    idParam.values = Arrays.asList("contentId-123", "contentId-456", "xyz"); 

    List<SearchParam> mustParams = Arrays.asList(versionParam, idParam); 

    ObjectMapper mapper = new ObjectMapper(); 

    SimpleModule module = new SimpleModule(); 
    module.addSerializer(SearchParam.class, new SearchParamSerializer()); 
    module.addSerializer(DeleteQuery.class, new DeleteQuerySerializer()); 
    mapper.registerModule(module); 

    List<String> mustParamList = new ArrayList<>(); 
    for (SearchParam param : mustParams) { 
     mustParamList.add(mapper.writeValueAsString(param)); 
    } 

    DeleteQuery deleteQuery = new DeleteQuery(); 
    deleteQuery.mustParams = mustParamList; 

    String serialized = mapper.writeValueAsString(deleteQuery); 
    JsonNode jsonNode = mapper.readTree(serialized); 
    String s = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonNode); 
    System.out.println(s); 
} 

は最後に、この出力を得た:

{ 
    "query": { 
     "bool": { 
      "must": [{ 
       "term": { 
        "version": { 
         "value": "published" 
        } 
       } 
      }, { 
       "terms": { 
        "contentId": ["contentId-123", "contentId-456", "xyz"] 
       } 
      }] 
     } 
    } 
} 

:)

これは適切な解決策ではありませんが、はい、私は現在ブロック解除されており、今後も継続できます。 :)

関連する問題