Hi Ian,
On Fri, Jul 17, 2009 at 02:51:06PM -0400, Stevens, Ian wrote:
> I'm working on a project which uses Jersey to convert objects to JSON.
> I'd like to be able to write out nested lists, like so:
>  
>     {"data":[["one", "two", "three"], ["a", "b", "c"]]}
>  
> The object I'd like to convert first represented data as a
> <LinkedList<LinkedList<String>>>, and I figured Jersey would just do the
You needed concrete List implementation, as JAXB refused to play 
with the interface List, right?
> right thing. The above was output as a list of nulls:
>  
>     {"data":[null, null]}
>  
> After reading that nested objects need to be wrapped, I tried the
Where did you read that? I presume it is part of JAXB docs?
> following:
>  
> @XmlRootElement(name = "foo")
> @XmlType(propOrder = {"data"})
> public class Foo
> {
>     private Collection<FooData> data = new LinkedList<FooData>();
>  
>     @XmlElement(name = "data")
>     public Collection<FooData> getData()
>     {
>         return data;
>     }
>  
>     public void addData(Collection data)
>     {
>         FooData d = new FooData();
>         for(Object o: data)
>         {
>             d.getData().add(o == null ? (String)o : o.toString());
>         }
>         this.data.add(d);
>     }
>  
>     @XmlRootElement(name = "FooData")
>     public static class FooData
>     {
>         private Collection<String> data = new LinkedList<String>();
>  
>         @XmlElement
>         public Collection<String> getData()
>         {
>             return data;
>         }
>     }
> }
>  
> That code outputs what's below, which is closer to what I want:
>  
>     {"data":[{"data":["one", "two", "three"]},{"data":["a", "b", "c"]}]}
>  
> I want the first data to be a list of lists, not a list of one-element
> dictionaries. How do I achieve this?
I am sorry, but IMHO using the JAXB->JSON way, you will not be able to get what you want.
You might want to use the low-level JSON approach [1] for generating the JSON,
or Tatu's Java->JSON provider [2].
~Jakub
[1]
https://jersey.dev.java.net/documentation/1.1.1-ea/user-guide.html#d4e645
[2]
http://www.cowtowncoder.com/blog/archives/2009/03/entry_229.html
>  
> Here's my JAXBContentResolver:
>  
> @Provider
> public class JAXBContextResolver implements ContextResolver<JAXBContext>
> {
>     private JAXBContext context;
>     private Set<Class<?>> types;
>  
>     // Only parent classes are required here. Nested classes are
> implicit.
>     protected Class<?>[] classTypes = new Class[] {Foo.class};
>  
>     protected Set<String> jsonArray = new HashSet<String>(1) {
>         {
>             add("data");
>         }
>     };
>  
>     public JAXBContextResolver() throws Exception
>     {        
>         Map<String, Object> props = new HashMap<String, Object>();
>         props.put(JSONJAXBContext.JSON_NOTATION,
> JSONJAXBContext.JSONNotation.MAPPED);
>         props.put(JSONJAXBContext.JSON_ROOT_UNWRAPPING, Boolean.TRUE);
>         props.put(JSONJAXBContext.JSON_ARRAYS, jsonArray);
>         this.types = new HashSet<Class<?>>(Arrays.asList(classTypes));
>         this.context = new JSONJAXBContext(classTyes, props);
>     }
>     
>     public JAXBContext getContext(Class<?> objectType)
>     {
>         return (types.contains(objectType)) ? context : null;
>     }
> }
> 
> thanks,
> Ian.