Hi Jakub,
Excellent - thanks for this. Will try it now. Great to have a test case.
Cheers
James.
________________________________________
From: Jakub.Podlesak_at_Sun.COM [Jakub.Podlesak_at_Sun.COM]
Sent: 08 October 2009 16:21
To: users_at_jersey.dev.java.net
Cc: James Allchin
Subject: Re: [Jersey] RE: Custom Natural JAXBContextResolver Problem - Single Element Arrays
On Wed, Oct 07, 2009 at 09:38:11AM -0700, James Allchin wrote:
> Hi All,
>
> Sorry for the follow-up... I still have this issue but wanted to add a little more info.
>
> I have also explicitly set the location of the config package within my web.xml.
>
> This also does not help - because as described I know that the JAXBContextResolver is being loaded at startup (it's confirmed in the JVM logs).
>
> Any thoughts?
Hi James,
Sorry for not replying earlier.
I have tried to reproduce your issue, but have not succeeded.
Please see the attached maven project. After unzipping
you can try to cd JsonListIssues and mvn clean compile exec:java,
then you should be able to GET [{"a":"a string","b":1},{"a":"a string","b":1}]
from
http://localhost:9998/myresource/2
and [{"a":"a string","b":1}] from
http://localhost:9998/myresource/1
If this does not work at your environment (are you using GFv3?),
switching to the mapped notation should work. (please see the uncommented line
at MyJAXBContextProvider class.
Could you please let me know, how the attached works for you, and could you try
to create such a simple project demonstrating your issue and send it back to me?
(feel free to send it privately, if you wish).
Thanks,
~Jakub
>
> Cheers
>
> James
>
> ________________________________________
> From: James Allchin
> Sent: 05 October 2009 20:25
> To: users_at_jersey.dev.java.net
> Subject: Custom Natural JAXBContextResolver Problem - Single Element Arrays
>
> Hi All,
>
> I have a ContextResolver so that I can use Natural JSON notation:
>
> package com.knowledgemill.rest.main;
>
> import com.knowledgemill.entities.*;
>
> import com.sun.jersey.api.json.JSONJAXBContext;
> import com.sun.jersey.api.json.JSONConfiguration;
> import java.util.HashMap;
> import java.util.HashSet;
> import java.util.Map;
> import javax.ws.rs.ext.ContextResolver;
> import javax.ws.rs.ext.Provider;
> import javax.xml.bind.JAXBContext;
>
> /*
> * This class is used to make sure that when using JSON when an array contains a single
> * element it still comes back as an array - makes it much easier to deal with
> */
>
>
> @Provider
> public class JAXBContextResolver implements ContextResolver<JAXBContext> {
>
> private JAXBContext context;
>
> private Class<?>[] types = {
> Artifact.class
> , ArtifactPermission.class
> , AttachedDoc.class
> , AttachedDocArtifact.class
> , AuditMessage.class
> , Container.class
> , ContainerPermission.class
> , Context.class
> , ContextFolder.class
> , Credential.class
> , DBLogMessage.class
> , EmailArtifact.class
> , EmailRecipient.class
> , ExtendedAttribute.class
> , ExtendedEmail.class
> , Group.class
> , InternalArtifact.class
> , InternalUser.class
> , ManagedDocArtifact.class
> , StorageTier.class
> , SystemAttribute.class
> , TreeNode.class
> , User.class
> , UserEmailAddress.class
> };
>
>
> public JAXBContextResolver() throws Exception {
> Map props = new HashMap<String, Object>();
> this.context = new JSONJAXBContext(JSONConfiguration.natural().build(), types);
> }
>
> public JAXBContext getContext(Class<?> objectType) {
> for (Class<?> type : types) {
> if (type == objectType) {
> return context;
> }
> }
> return null;
> }
>
>
> }
>
>
> As you can see I have a number of classes which I have specified should be targeted by the this ContextResolver.
>
> Now according to the documentation, the NATURAL configuration should mean that single element arrays will indeed be respected as a array within JSON (instead of returning a single object).
>
> If I take one of my methods which returns List<UserEmailAddress>:
>
> @GET
> @Path("user/{userId}/users/{targetUserId}/emailaddresses/")
> @Produces({"application/xml","application/json"})
> public List<UserEmailAddress> getUserEmailAddresses (@PathParam("userId") String userId
> , @PathParam("targetUserId") String targetUserId
> ) {
>
> List<UserEmailAddress> returnedEmailAddresses = null;
> try {
> logger.debug("userId value is " + userId);
> returnedEmailAddresses = dA.getUserEmailAddresses( targetUserId);
> }
> catch (Exception e) {
> e.printStackTrace();
> }
> return returnedEmailAddresses;
> }
>
> If I exercise this call (using JSON) where it returns multiple elements – I end up with a response shown below:
>
> {"UserEmailAddress": [
> {
> "userId": "7452272EBA160D9AE040A8C048010EEB",
> "smtpAddress": "david.campbell_at_knowledgemill.com",
> "primary": "false",
> "legacy": "true"
> },
> {
> "userId": "7452272EBA160D9AE040A8C048010EEB",
> "smtpAddress": "dcampbell_at_knowledgemill.com",
> "primary": "true",
> "legacy": "false"
> }
> ]}
>
> This looks good – I can see the array notation in the JSON.
>
> If I exercise this call (using JSON) where it returns a single element – I end up with a response shown below:
>
> {"UserEmailAddress": {
> "userId": "7452272EBA160D9AE040A8C048230EEB",
> "smtpAddress": "john_at_knowledgemill.com",
> "primary": "true",
> "legacy": "false"
> }}
>
> This is bad – the single element is not coming back as an array.
>
> From my understanding this should have been rectified when using a NATURAL JSON notation. It does not work for me.
>
> I have also tried fixing the arrays specifically with the default MAPPED notation e.g.:
>
> JSONConfiguration.mapped().arrays( NAMES OF ARRAYS HERE).build()
>
> This also does not work.
>
> It appears that the ContextResolver is having no effect. However, I have confirmed that the Provider is being loaded on startup.
>
> Any help – much appreciated.
>
> Cheers.
>
> James
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
--
Jakub Podlešák
Software Engineer at SUN Microsystems And CZJUG Co-Leader
http://blogs.sun.com/japod