users@jersey.java.net

Re: [Jersey] customizing JSON rendering in Jersey

From: Arul Dhesiaseelan <arul_at_fluxcorp.com>
Date: Tue, 29 Apr 2008 08:55:02 -0600

Hi Jakub,

Thanks for helping me out. This solution works great for me. I am using
Jersey 0.7. I have a related question about custom resolvers.

What if I have multiple resources and how do I register custom JAXB
context resolver specific to a resource?

Cheers,
Arul

Jakub Podlesak wrote:
> Hi Arul,
>
> please look for a solution in line...
>
> On Mon, Apr 28, 2008 at 06:46:23PM -0600, Arul Dhesiaseelan wrote:
>
>> Hi,
>>
>> I would like to customize JSON rendering in Jersey. Here is my resource
>> class and associated JAXB classes.
>>
>> CustomerResource.java
>>
>> @Singleton
>> @Path("/customers")
>> public class CustomerResource {
>>
>> private static Map<Long, Customer> customers = new
>> ConcurrentHashMap<Long, Customer>();
>>
>> @GET @Path("/list")
>> @ProduceMime({"application/json"})
>> public Customers getCustomers() throws IOException {
>> Customers c = new Customers();
>> c.setCustomers(customers.values());
>> return c;
>> }
>>
>> }
>> Customers.java
>>
>> @XmlRootElement
>> public class Customers {
>> private Collection<Customer> customers;
>>
>> public Collection<Customer> getCustomers() {
>> return customers;
>> }
>>
>> public void setCustomers(Collection<Customer> c) {
>> this.customers = c;
>> }
>> }
>>
>> Customer.java
>> @XmlRootElement(name = "customer")
>> public class Customer {
>> private Long id;
>> private String name;
>> //getters and setters
>> }
>>
>> When I access the "/customers/list" URL, I get the following JSON response.
>>
>> {"customers":{"customers":[{"id":"2","name":"Test2"},{"id":"1","name":"Test1"}]}}
>>
>> I am not sure why the customers tag is listed twice. I would like to
>> generate something like
>>
>
> that is because the original xml (JAXB generated) looks like:
>
> <customers><customers><id>2</id2><name>Test2</name></customers>...
> ^^^
> the first <customers/> element corresponds to Customers.class
> while the second one corresponds to Customers#customers collection
>
> It is probably a regression, because the very first (wrapping) element should
> be stripped off by default. Which Jersey build do you use?
>
>
>> {"customers":[{"id":"2","name":"Test2"},{"id":"1","name":"Test1"}]}
>>
>> How do I customize JSON rendering in Jersey?
>>
>
> You will need to implement your custom JAXB context resolver. In your case
> not only due to the above mentioned regression, but also to deal with
> one-element customer collections (see [1] for details).
>
> Your resolver could look like (did not test it):
>
> @Provider
> public class JAXBContextResolver implements ContextResolver<JAXBContext> {
>
> private JAXBContext context;
> private Class[] types = {Customers.class, Customer.class};
>
> public JAXBContextResolver() throws Exception {
> Map props = new HashMap<String, Object>();
> props.put(JSONJAXBContext.JSON_NOTATION, "MAPPED");
> props.put(JSONJAXBContext.JSON_ROOT_UNWRAPPING, Boolean.TRUE);
> props.put(JSONJAXBContext.JSON_ARRAYS, "[\"customers\"]");
> this.context = new JSONJAXBContext(types, props);
> }
>
> public JAXBContext getContext(Class<?> objectType) {
> return (types[0].equals(objectType) || types[1].equals(objectType)) ? context : null;
> }
> }
>
> HTH,
>
> ~Jakub
>
> [1]http://blogs.sun.com/japod/entry/missing_brackets_at_json_one
>
>
>> Please clarify.
>>
>> Thank you,
>> Arul
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
>
> _________________________________________________
> Scanned by MessageLabs for the Super Flux Friends
> _________________________________________________
>