In XStream is there a better way to marshall/unmarshall List<Object>'s in JSON and Java In XStream is there a better way to marshall/unmarshall List<Object>'s in JSON and Java ajax ajax

In XStream is there a better way to marshall/unmarshall List<Object>'s in JSON and Java


I agree with other poster in that XStream is not a good fit -- it's an OXM (Object/Xml Mapper), and JSON is handled as a secondary output format using XML processing path. This is why a "convention" (of how to convert hierarchich xml model into object-graph model of json and vice versa) is needed; and your choice boils down to using whatever is least intrusive of sub-optimal choices.That works ok if XML is your primary data format, and you just need some rudimentary JSON(-like) support.

To get good JSON-support, I would consider using a JSON processing library that does real OJM mapping (I assume Svenson does too, but additionally), such as:

Also: even if you do need to support both XML and JSON, you are IMO better off using separate libraries for these tasks -- objects (beans) to use on server-side need not be different, just serialization libs that convert to/from xml and json.


I realize this is off-topic, but I'd like to present a solution in svenson JSON.

Do you really need public fields in your domain classes? Apart from having to use properties, svenson can handle cases like this with a more simple JSON output with a discriminator property

class Message{   // .. your properties with getters and setters ..    // special property "type" acts a signal for conversion}class MessageOther{  ...}List list = new ArrayList();list.add(new Message());list.add(new MessageOther());list.add(new Message());String jsonDataSet = JSON.defaultJSON().forValue(list);

would output JSON like

[    {"type":"message", ... },     {"type":"message_other", ... },     {"type":"message", ... }]

which could be parsed again with code like this

    // configure reusable parse instance    JSONParser parser = new JSONParser();    // type mapper to map to your types    PropertyValueBasedTypeMapper mapper = new PropertyValueBasedTypeMapper();    mapper.setParsePathInfo("[]");    mapper.addFieldValueMapping("message", Message.class);    mapper.addFieldValueMapping("message_other", MessageOther.class);    parser.setTypeMapper(mapper);    List list = parser.parse(List.class, jsonDataset);


A svenson type mapper based on the full class name would look something like this

public class ClassNameBasedTypeMapper extends PropertyValueBasedTypeMapper{    protected Class getTypeHintFromTypeProperty(String value) throws IllegalStateException    {        try        {            return Class.forName(value);        }        catch (ClassNotFoundException e)        {            throw new IllegalStateException(value + " is no valid class", e);        }    }}

which is not an ideal implementation as it inherits the configuration of PropertyValueBasedTypeMapper without really needing. (should include a cleaner version in svenson)

The setup is very much like above

JSONParser parser = new JSONParser();ClassNameBasedTypeMapper mapper = new ClassNameBasedTypeMapper();mapper.setParsePathInfo("[]");parser.setTypeMapper(mapper);List foos = parser    .parse( List.class, "[{\"type\":\"package.Foo\"},{\"type\":\"package.Bar\"}]");