Я пытаюсь создать следующий JSON динамически на основе ввода PARAMS т.е. (версия содержания, в списке содержимых идентификаторов)Java + Джексон: Как сериализовать объект, содержащий массив/список других объектов
{
"query": {
"bool": {
"must": [
{
"term": {
"version": {
"value": "published"
}
}
},
{
"terms": {
"contentId": [
"contentId-123",
"contentId-456"
]
}
}
]
}
}
}
Вышеупомянутый json - это тело запроса для запроса удаления с помощью эластичного поиска. version
и contentId
, упомянутые в приведенных выше json, являются действительными полями/атрибутами объекта контента или модели данных.
Я получаю это исключение при сериализации объекта:
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()
, перегруппированы jsonGen.writeStartObject()
и jsonGen.writeEndObject()
относительно value.isMultivalued()
), но все равно не получится, как ожидалось.
После многократного переполнения и переполнения стека я получил несколько ссылок, но они больше говорят о библиотеке Gson и/или находятся на python.
Любая помощь!
Да. Но у нас есть другой проект, основанный на java API-интерфейсе flex-поиска, и мы должны это использовать. Я не могу напрямую использовать API-интерфейс QueryBuilder для java API. Более того, этот проект отличается от моего или нашей команды. – manoj
Я собираюсь взглянуть на ваш код. –