Java+;Jackson:如何序列化包含其他对象数组/列表的对象

Java+;Jackson:如何序列化包含其他对象数组/列表的对象,java,json,serialization,jackson,Java,Json,Serialization,Jackson,我试图根据输入参数(内容的版本、内容ID列表)动态生成以下json 上面的json是弹性搜索删除请求的查询体。 上述json中提到的version和contentId是内容对象或数据模型的实际字段/属性 序列化对象时出现此异常: com.fasterxml.jackson.core.JsonGenerationException: Can not start an object, expecting field name at com.fasterxml.jackson.core.Jso

我试图根据输入参数(内容的版本、内容ID列表)动态生成以下json

上面的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);
}
class SearchParam{
布尔是多值的;
字符串字段名;
字符串值;
列表值;
@凌驾
公共字符串toString(){
最终StringBuilder sb=新StringBuilder(“SearchParam{”);
sb.append(“isMultivalued=”).append(isMultivalued);
sb.append(“,fieldName=”).append(fieldName).append(“\”);
sb.append(“,value=”)。append(value)。append(“\”);
sb.append(“,values=”)。append(values);
某人附加('}');
使某人返回字符串();
}
}
类DeleteQuery{
列表参数;
}
类DeleteQuerySerializer扩展了StdSerializer{
受保护的DeleteQuerySerializer(t类){
超级(t);
}
公共DeleteQuerySerializer(){
这个(空);
}
@凌驾
public void serialize(DeleteQuery值、JsonGenerator jsonGen、SerializerProvider提供程序)引发IOException{
jsonGen.writeStartObject();
writeObjectFieldStart(“查询”);
jsonGen.writeObjectFieldStart(“bool”);
jsonGen.writeArrayFieldStart(“必须”);
for(SearchParam参数:value.mustParams){
jsonGen.writeObject(参数);
}
jsonGen.writeEndObject();
}
}
类SearchParamSerializer扩展了StdSerializer{
受保护的SearchParamSerializer(t类){
超级(t);
}
受保护的SearchParamSerializer(){
这个(空);
}
@凌驾
public void serialize(SearchParam值、JsonGenerator jsonGen、SerializerProvider提供程序)引发IOException、JsonGenerationException{
jsonGen.writeStartObject();
if(value.isMultivalued){
jsonGen.writeObjectFieldStart(“条款”);
jsonGen.writeArrayFieldStart(value.fieldName);
for(字符串v:value.values){
jsonGen.WRITETSTRING(五);
}
jsonGen.writeEndArray();
}否则{
jsonGen.writeObjectFieldStart(“术语”);
jsonGen.writeObjectFieldStart(value.fieldName);
jsonGen.writeStringField(“value”,value.value);
}
jsonGen.writeEndObject();
}
}
@试验
public void dummyTest()引发JsonProcessingException{
SearchParam versionParam=新的SearchParam();
versionParam.fieldName=“version”;
versionParam.IsMultiValue=false;
versionParam.value=“已发布”;
SearchParam idParam=新的SearchParam();
idParam.fieldName=“contentId”;
idParam.IsMultiValue=true;
idParam.values=Arrays.asList(“contentID-1”、“contentID-2”、“contentID-3”);
List mustParams=Arrays.asList(versionParam,idParam);
ObjectMapper mapper=新的ObjectMapper();
SimpleModule=新的SimpleModule();
module.addSerializer(SearchParam.class,新的SearchParamSerializer());
addSerializer(DeleteQuery.class,新的DeleteQuerySerializer());
映射器注册表模块(模块);
DeleteQuery DeleteQuery=新建DeleteQuery();
deleteQuery.mustParams=mustParams;
String serialized=mapper.writerWithDefaultPrettyPrinter().writeValueAsString(deleteQuery);
System.out.println(序列化);
}
参考:

我在代码中做了一些调整(例如,在
SearchParamSerializer.serialize()
中,重新排列了
jsonGen.writeStartObject()
jsonGen.writeEndObject()
关于
value.isMultivalued()
条件),但仍然没有得到预期的结果

在谷歌搜索和堆栈溢出之后,我得到了一些链接,但他们更多地讨论了Gson库和/或python


任何帮助

顺便问一下,您是否查看了此API:?

我的解决方案现在继续

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();
    }
}
最后,获得以下输出:

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


这不是一个正确的解决方案,但是的,我现在已解除阻止,可以继续。:)

对。但是,我们有一个基于elastic search的java API的不同项目,我们必须利用它。我不能直接使用elastic的java API的QueryBuilder。此外,不同的项目超出了我或我们团队的范围。
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"]
                }
            }]
        }
    }
}