Java 在Jackson中使用自定义序列化程序序列化嵌套对象时出现JsonGenerationException
这是我想要序列化的类Java 在Jackson中使用自定义序列化程序序列化嵌套对象时出现JsonGenerationException,java,serialization,jackson,jackson2,jackson-databind,Java,Serialization,Jackson,Jackson2,Jackson Databind,这是我想要序列化的类 public class ItemRow<T> { private String id; private List<T> items; } 应该给 { "abc":["item1","item2","item3"] } { "combined": { "abc": ["item1", "item2", "item3"], "cde": ["item4", "item5"]
public class ItemRow<T> {
private String id;
private List<T> items;
}
应该给
{
"abc":["item1","item2","item3"]
}
{
"combined": {
"abc": ["item1", "item2", "item3"],
"cde": ["item4", "item5"]
}
}
现在是后一种情况
ItemRow item2 = new ItemRow("cde", Arrays.asList("item4, item5"));
ItemRow item = new ItemRow("combined", Arrays.asList(item1,item2));
result = mapper.writeValueAsString(item);
System.out.println(result);
应该给
{
"abc":["item1","item2","item3"]
}
{
"combined": {
"abc": ["item1", "item2", "item3"],
"cde": ["item4", "item5"]
}
}
但我在序列化后者时遇到异常。第一个按预期工作。所以我相信递归序列化失败了,但我无法找出原因
这是个例外
com.fasterxml.jackson.core.JsonGenerationException: Can not start an object, expecting field name (context: Object)
at com.fasterxml.jackson.core.JsonGenerator._reportError(JsonGenerator.java:1961)
at com.fasterxml.jackson.core.json.JsonGeneratorImpl._reportCantWriteValueExpectName(JsonGeneratorImpl.java:244)
at com.fasterxml.jackson.core.json.WriterBasedJsonGenerator._verifyValueWrite(WriterBasedJsonGenerator.java:866)
at com.fasterxml.jackson.core.json.WriterBasedJsonGenerator.writeStartObject(WriterBasedJsonGenerator.java:279)
at hello.ItemRowSerializer.serialize(ItemRow.java:58)
at hello.ItemRowSerializer.serialize(ItemRow.java:42)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
at com.fasterxml.jackson.databind.ObjectMapper.writeValue(ObjectMapper.java:2655)
at com.fasterxml.jackson.core.base.GeneratorBase.writeObject(GeneratorBase.java:381)
at hello.ItemRowSerializer.serialize(ItemRow.java:67)
at hello.ItemRowSerializer.serialize(ItemRow.java:42)
序列化程序实现
class ItemRowSerializer extends JsonSerializer<ItemRow> {
@Override
public void serialize(ItemRow itemRow, JsonGenerator jgen, SerializerProvider serializerProvider) throws IOException {
String id = itemRow.getId();
List<Object> items = itemRow.getItems();
if (items.isEmpty()) {
jgen.writeStartObject();
jgen.writeFieldName(id);
jgen.writeStartArray();
jgen.writeEndArray();
jgen.writeEndObject();
}
else {
jgen.writeStartObject();
Object item = items.get(0);
jgen.writeFieldName(id);
if (item instanceof ItemRow){
for (Object i : items) {
//ItemRow temp = (ItemRow) i;
//jgen.writeObjectField(temp.getId(), temp);
//jgen.writeObjectField(id, i);
jgen.writeStartObject();
jgen.writeObject(i);
jgen.writeEndObject();
}
}
else {
//jgen.writeFieldName(id);
jgen.writeStartArray();
for (Object arg : items) {
jgen.writeString(arg.toString());
}
jgen.writeEndArray();
}
}
jgen.writeEndObject();
}
}
class ItemRowSerializer扩展了JsonSerializer{
@凌驾
公共void序列化(ItemRow ItemRow、JsonGenerator jgen、SerializerProvider SerializerProvider)引发IOException{
String id=itemrrow.getId();
List items=itemRow.getItems();
if(items.isEmpty()){
jgen.writeStartObject();
jgen.writeFieldName(id);
jgen.writestarray();
jgen.writeEndArray();
jgen.writeEndObject();
}
否则{
jgen.writeStartObject();
对象项=项。获取(0);
jgen.writeFieldName(id);
如果(ItemRow的项目实例){
用于(对象一:项目){
//ItemRow温度=(ItemRow)i;
//jgen.writeObjectField(temp.getId(),temp);
//jgen.writeObjectField(id,i);
jgen.writeStartObject();
jgen.writeObject(i);
jgen.writeEndObject();
}
}
否则{
//jgen.writeFieldName(id);
jgen.writestarray();
用于(对象参数:项){
jgen.writeString(arg.toString());
}
jgen.writeEndArray();
}
}
jgen.writeEndObject();
}
}
您的序列化程序算法不正确。代码在上面。直接反序列化对象时,不需要启动对象。我删除了这些步骤并最小化了代码
示例测试
@Test
public void serializeTest() throws JsonProcessingException
{
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(ItemRow.class, new ItemRowSerializer());
mapper.registerModule(module);
ItemRow item1 = new ItemRow("abc", Arrays.asList("item1", "item2", "item3"));
String result = mapper.writeValueAsString(item1);
System.out.println(result);
ItemRow item2 = new ItemRow("cde", Arrays.asList("item4", "item5"));
ItemRow item6 = new ItemRow("deeper-1", Arrays.asList("item6", "item7"));
ItemRow item7 = new ItemRow("deeper-2", Arrays.asList("item6", "item7"));
ItemRow item8 = new ItemRow("deeper", Arrays.asList(item6, item7));
ItemRow item3 = new ItemRow("inner-1", Arrays.asList("item6", "item7"));
ItemRow item4 = new ItemRow("inner-2", Arrays.asList("item6", "item7"));
ItemRow item5 = new ItemRow("inner", Arrays.asList(item3, item4, item8));
ItemRow item = new ItemRow("combined", Arrays.asList(item1,item2,item5));
result = mapper.writeValueAsString(item);
System.out.println(result);
}
算法
public class ItemRowSerializer extends JsonSerializer<ItemRow>
{
@Override
public void serialize(ItemRow itemRow, JsonGenerator jgen, SerializerProvider serializerProvider) throws IOException
{
jgen.writeStartObject();
writeInnerObject(jgen, itemRow);
jgen.writeEndObject();
}
private void writeStringArr(JsonGenerator jgen, List items) throws IOException
{
jgen.writeStartArray();
for (Object arg : items)
{
jgen.writeString(arg.toString());
}
jgen.writeEndArray();
}
private void writeInnerObject(JsonGenerator jgen, ItemRow row) throws IOException
{
jgen.writeFieldName(row.getId());
if (row.getItems().size() > 0 && row.getItems().get(0) instanceof ItemRow)
{
jgen.writeStartObject();
for (int i = 0; i < row.getItems().size(); i++)
{
ItemRow innerRow = (ItemRow) row.getItems().get(i);
if( innerRow.getItems().size() > 0 && innerRow.getItems().get(0) instanceof ItemRow )
{
writeInnerObject(jgen, innerRow);
}
else
{
jgen.writeFieldName(innerRow.getId());
writeStringArr(jgen, innerRow.getItems());
}
}
jgen.writeEndObject();
}
else
{
writeStringArr(jgen, row.getItems());
}
}
}
公共类ItemRowSerializer扩展JsonSerializer
{
@凌驾
公共void序列化(ItemRow ItemRow、JsonGenerator jgen、SerializerProvider SerializerProvider)引发IOException
{
jgen.writeStartObject();
writeInnerObject(jgen,itemRow);
jgen.writeEndObject();
}
私有void writeStringar(JsonGenerator jgen,列表项)引发IOException
{
jgen.writestarray();
用于(对象参数:项)
{
jgen.writeString(arg.toString());
}
jgen.writeEndArray();
}
私有void writeInnerObject(JsonGenerator jgen,ItemRow行)引发IOException
{
jgen.writeFieldName(row.getId());
if(row.getItems().size()>0&&row.getItems().get(0)instanceof ItemRow)
{
jgen.writeStartObject();
对于(int i=0;i0&&innerRow.getItems().get(0)instanceof ItemRow)
{
writeInnerObject(jgen,innerRow);
}
其他的
{
jgen.writeFieldName(innerRow.getId());
writeStringArr(jgen,innerRow.getItems());
}
}
jgen.writeEndObject();
}
其他的
{
writeStringArr(jgen,row.getItems());
}
}
}
这不会给出预期的输出。此{“组合”:[{“abc”:[“item1”、“item2”、“item3”]},{“cde”:[“item4、item5”]}
的输出。正如您所看到的,它具有要“组合”的列表节点,但我想要一个对象节点。见上文中的question@brainstorm代码正在运行,我添加了更复杂的示例。我会做一些测试,一旦我确认它对不同的输入有效,我就会接受答案。我还有两个关于杰克逊的问题。如果你有时间,请看看你是否能帮忙!我试图编写反序列化程序,但在映射中使用时无法工作。你能在这里提供一些意见吗。。