I think you should not recursively call `serialize()` with
`getArgs()`, if you do not want values wrapped as JSON Objects. You
probably need to refactor code a bit, so that outermost cases outputs
full Object, args case just appends name/value pairs.

Also one simplification I suggest is that instead of

                ObjectCodec oc = jp.getCodec();
                JsonNode node = oc.readTree(jp);

just call

     JsonNode node = jp.readValueAsTree()

(it won't make a difference in working of code, but is bit more readable)

-+ Tatu +-

On Wed, Dec 19, 2018 at 4:15 PM matt Smith <[email protected]> wrote:
>
> Here is update to my original post. ignore the above though for most part 
> they are the same.
> copying and pasting from SO is having formatting issues. so I have to delete 
> couple of my posts above..
>
>
> I want to serialize/deserialize Record object that has recursive references. 
> The POJO itself cannot be modified since it is part of legacy code.
>
>
>     public class Record<T> {
>
>         private TypeEnum typeEnum;
>         private List<T> args;
>
>         public Record(TypeEnum typeEnum, List<T> args) {
>             this.typeEnum = typeEnum;
>             this.args = args;
>         }
>
>         public TypeEnum getTypeEnum() {
>             return typeEnum;
>         }
>
>         public void setTypeEnum(TypeEnum typeEnum) {
>             this.typeEnum = typeEnum;
>         }
>
>         public List<T> getArgs() {
>             return args;
>         }
>
>         public void setArgs(List<T> args) {
>             this.args = args;
>         }
>     }
>
>     enum TypeEnum {
>         STR("str"),
>         FOO("foo"),
>         REC("rec");
>
>         private String name;
>          TypeEnum(String name) {
>             this.name=name;
>         }
>     }
>
>     class RecordSerializer extends JsonSerializer<Record> {
>
>         @Override
>         public void serialize(Record record, JsonGenerator jgen, 
> SerializerProvider serializerProvider) throws IOException {
>             jgen.writeStartObject();
>             switch (record.getTypeEnum()) {
>                 case STR:
>                     jgen.writeFieldName(record.getTypeEnum().name());
>                     jgen.writeStartArray();
>                     for (Object arg : record.getArgs()) {
>                         jgen.writeString(arg.toString());
>                     }
>                     jgen.writeEndArray();
>                     break;
>                 case FOO:
>                     jgen.writeFieldName(record.getTypeEnum().name());
>                     jgen.writeStartArray();
>                     for (Object arg : record.getArgs()) {
>                         jgen.writeString(arg.toString());
>                     }
>                     jgen.writeEndArray();
>                     break;
>                 case REC:
>                     jgen.writeFieldName(record.getTypeEnum().name());
>                     jgen.writeStartArray(); // LINE 94
>                     for (Object arg : record.getArgs()) {
>                         serialize((Record) arg, jgen, serializerProvider);
>                     }
>                     jgen.writeEndArray();    // LINE 98
>                     break;
>             }
>                    jgen.writeEndObject();
>         }
>
>         class RecordDeSerializer extends JsonDeserializer<Record> {
>
>             @Override
>             public Record deserialize(JsonParser jp, DeserializationContext 
> deserializationContext) throws IOException, JsonProcessingException {
>                 ObjectCodec oc = jp.getCodec();
>                 JsonNode node = oc.readTree(jp);
>                 Iterator<Map.Entry<String, JsonNode>> fields = node.fields();
>
>
>                 while (fields.hasNext()) {
>                     Map.Entry<String, JsonNode> entry = fields.next();
>                     System.out.println(entry.getKey() + "====" + 
> entry.getValue());
>                 }
>
>                 return new Record(TypeEnum.STR, Arrays.asList("a", "b", "c"));
>             }
>         }
>     }
>
>
>     Here is a unit-test that I wrote
>
>         @JsonSerialize(keyUsing = RecordSerializer.class)
>             private Record rec;
>
>             ObjectMapper mapper = new ObjectMapper();
>
>         public void testSeriaziation() {
>                Record rec1 = new Record(TypeEnum.STR, Arrays.asList("sup1", 
> "sup2", "sup3"));
>             Record rec2 = new Record(TypeEnum.FOO, Arrays.asList("sup4", 
> "sup5"));
>
>             rec = new Record(TypeEnum.REC, Arrays.asList(rec1, rec2));
>
>                 final String jsonResult = mapper.writeValueAsString(rec);
>
>                 System.out.println(jsonResult);
>         }
>
>     The output from this test is
>
>
>
>      {
>     "REC": [{
>     "STR": ["sup1", "sup2", "sup3"]
>     }, {
>     "FOO": ["sup4", "sup5"]
>     }]
>       }
>
>
>     while the expected output is
>
>     {
>  "REC": {
>  "STR": ["sup1", "sup2", "sup3"],
>  "FOO": ["sup4", "sup5"]
>  }}
>
>
> Notice, I want "STR" and "FOO" to be siblings in root node "REC"
>
> I believe the way I call recursively is wrong. but I cannot figure out what 
> is wrong.
>
> if I comment out the lines 94 and 98, I get 
> com.fasterxml.jackson.core.JsonGenerationException: Can not start an object, 
> expecting field name (context: Object) exception
>
>
> --
> You received this message because you are subscribed to the Google Groups 
> "jackson-user" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to [email protected].
> To post to this group, send email to [email protected].
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"jackson-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to