Java+;Jackson:如何序列化包含其他对象数组/列表的对象
我试图根据输入参数(内容的版本、内容ID列表)动态生成以下json 上面的json是弹性搜索删除请求的查询体。 上述json中提到的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
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"]
}
}]
}
}
}