3

Using Flexjson, I am trying to serialize an object ("Payload") that contains a List. Each MyBean has a field "items", which is a Map>. When I serialize this Payload object, the map field ("items") is empty.

public class Payload {

private List<MyBean> myBeans = new ArrayList<MyBean>();

//the JSON returned has blank values for myBeans.values.items
public String toJson() {
        return new JSONSerializer()
            .exclude("*.class")
            .include("myBeans")
            .serialize(this);
}

}

However, when I serialize the MyBean object directly, it works fine.

public class MyBean {

private Map<String, List<SomeBean>> items = new HashMap<String, List<SomeBean>>();

//this works
public String toJson() {
        return new JSONSerializer()
            .exclude("*.class")
            .deepSerialize(this);
}

}

Any suggestions?

davedonohue
  • 212
  • 5
  • 14

1 Answers1

2

After trying a bunch of things, I found this solution. I created a custom transformer for maps. Just copied the Flexjson MapTransformer and commented out a IF condition. New code below

public class Payload {

    private List<MyBean> myBeans = new ArrayList<MyBean>();

    //the JSON returned has blank values for myBeans.values.items
    public String toJson() {
            return new JSONSerializer()
                .exclude("*.class")
                .include("myBeans")
                .transform(new SOMapTransformer(), Map.class)
                .serialize(this);
    }
}


public class MyBean {

    private Map<String, List<SomeBean>> items = new HashMap<String, List<SomeBean>>();

    //this works
    public String toJson() {
            return new JSONSerializer()
                .exclude("*.class")
            .transform(new SOMapTransformer(), "items")
                .deepSerialize(this);
    }
}

Here is the custom SOMapTransformer:

import com.mycompany.mypackage.SomeBean;

import flexjson.JSONContext;
import flexjson.Path;
import flexjson.TypeContext;
import flexjson.transformer.AbstractTransformer;
import flexjson.transformer.TransformerWrapper;

    public class SOMapTransformer extends AbstractTransformer {

        public void transform(Object object) {
            JSONContext context = getContext();
            Path path = context.getPath();
            Map<String, List<SomeBean>> value = (Map<String, List<SomeBean>>) object;

            TypeContext typeContext = getContext().writeOpenObject();
            for (Object key : value.keySet()) {
                path.enqueue((String) key);

                //DPD 2013-11-04: This bloody line of code cost me 12 hours.  Comment it out!
//              if (context.isIncluded((String) key, value.get(key))) {

                    TransformerWrapper transformer = (TransformerWrapper)context.getTransformer(value.get(key));

                    if(!transformer.isInline()) {
                        if (!typeContext.isFirst()) getContext().writeComma();
                        typeContext.setFirst(false);
                        getContext().writeName(key.toString());
                    }

                    typeContext.setPropertyName(key.toString());

                    transformer.transform(value.get(key));

//              }

                path.pop();

            }
            getContext().writeCloseObject();
        }
davedonohue
  • 212
  • 5
  • 14
  • 1
    It never ceases to amaze me the hoops that Java JSON user jump through to do stuff that is blazingly simple if you just use maps and lists and forget about mapping stuff to other objects. – Hot Licks Nov 07 '13 at 23:19