我试图在输入参数的基础上动态生成以下json,即(内容' s版本,内容ID列表)
{
"query": {
"bool": {
"must": [
{
"term": {
"version": {
"value": "published"
}
}
},
{
"terms": {
"contentId": [
"contentId-123",
"contentId-456"
]
}
}
]
}
}
}
上面的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()
内部,重新安排jsonGen.writeStartObject()
和jsonGen.writeEndObject()
相对于value.isMultivalued()
条件),但仍未获得预期的结果
谷歌搜索和堆栈溢出后,我得到了很少的链接,但他们更多地谈论Gson库,和/或在python中。
任何帮助!
答案 0 :(得分:0)
答案 1 :(得分:0)
我的解决方法现在继续。
修改了DeleteQuery
和DeleteQuerySerializer
,如下所示:
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"]
}
}]
}
}
}
:)
这不是一个合适的解决方案,但是我现在已经解锁了,可以继续下去。 :)