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.