Marshalling an empty collection to json using jersey - json

I have a strange issue marshalling an empty object collection to json using jersey with the jaxb based json support. My object looks like
...
#XmlWrapper(name = "stuff") #XmlElement(name = "s")
private List<Foo> foos;
...
Marshaling this to json produces the expected results
... stuff: [{ "s": ... }, { "s": ... }] ...
except when the list is empty. I would expect to see
... stuff: [] ...
but I see
... stuff: [null] ...
instead. Any idea what's wrong? The problem seems to be related to the #XmlElementWrapper annotation, removing it I don't get the the stuff property in the output at all.

Are you serializing an empty list, or are you serializing an un-instantiated null object?
ie. I would expect:
private List<Foo> foos; - would serialize to 'stuff: [null]'
and I would also expect:
private List<Foo> foos = new ArrayList<Foo>(); - we serialize to 'stuff: []'
If that isn't the case, you can always direct Jackson (which is the default JSON serializer bundled with Jersey) to omit the writing of bean properties as null value..

I would suggest using POJO mapping based on Jackson. I am not sure why you want that intermediate "s" in there, but POJO would produce (and consume) simpler structure:
"stuff" : [ { ... }, { ... } ]
For that you need no annotations with POJO mapping; JAXB annotations are only needed for XML processing, since XML has no natural mechanism to distinguish arrays from objects (unlike JSON).

I managed to solve JSON array and primitive field "bug" in Jersey json library. Secret ingredient is JSONConfiguration and ContextResolver magic. See my following post it has a full code example, customized ContextResolver and rest Application class might be somewhat fuzzy logic in first look.
How to serialize Java primitives using Jersey REST
json array for zero or single-element Java lists
primitive integer or boolean fields without quotation chars

Related

Nested object JSON serialization in WebAPI

I am using .NET 4.0, MVC 4, Web API. I have following data structure:
Dictionary<Actor, Int32> TopActorToMovieCount = new Dictionary<Actor, Int32>(10);
And following entry in WebApiConfig:
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
In my Controller, I am returning TopActorToMovieCount this way:
[HttpGet]
public HttpResponseMessage HighestMovies()
{
return Request.CreateResponse(HttpStatusCode.OK, MvcApplication.TopActorToMovieCount);
}
But the JSON output it is giving is:
{"api.Models.Actor":137,"api.Models.Actor":125,"api.Models.Actor":99,"api.Models.Actor":96,"api.Models.Actor":83,"api.Models.Actor":82,"api.Models.Actor":81,"api.Models.Actor":79,"....
Why it is not giving JSON structure for object of Actor?
I am sure that I am missing something, bout couldn't figure out. I tried adding following, but it didn't work:
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
PS: When I switch to XML output, it works fine.
See similar question here: Not ableTo Serialize Dictionary with Complex key using Json.net
In this case, you are using "Actor" as the Key of your dictionary. Dictionary stores key/value pairs. So when creating the JSON response, it interprets the "Actor" as a key which is converted to a string, and the "Int32" as the value thus giving you
{"api.Models.Actor":137} or {key:value}
because
Actor.ToString() would result in "api.Models.Actor"
Here's a link to the definition of Dictionary: https://msdn.microsoft.com/en-us/library/xfhwa508(v=vs.110).aspx

Why is GSON not parsing these fields properly? (FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)

I have a JSONArray of JSONObjects that I'm trying to parse with GSON. I'm using FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES. It's parsing correctly for most fields (so the FieldNamingPolicy is set correct), but I'm getting null returned for
{
"image_sq_48x48_url": "url1",
"image_sq_64x64_url": "url2",
"image_sq_96x96_url": "url3"
}
with field names
imageSq48x48Url
imageSq64x64Url
imageSq96x96Url
Maybe a better question would be what is the proper camelCase? I have also tried
imageSq48X48Url
imageSq48X48url
If I map with #SerializedName("image_sq_96x96_url") it parses/populates correctly.
Unfortunately those fieldnames in your JSON don't conform to what Gson looks for using that strategy.
If you create a POJO and serialize it, you can see what the issue is:
class MyPojo
{
String imageSq48x48Url = "hi";
}
The resulting JSON from Gson using that strategy is:
{"image_sq48x48_url":"hi"}
It doesn't consider/look at numeric digits as leading indicators / start of a "word".
If you rename the field to:
String imageSq_48x48Url;
It would work with your JSON example and that strategy.
Basically, you either need to create your own class that implements FieldNamingStrategy that will handle those JSON fieldnames the way you want, or do what you're doing with the #SerializedName annotation.

Deep JSON serialization in Grails not working

I have an object structure like so:
class Message {
static mapWith="mongo"
static embedded = ['to', 'author', 'comments', 'tags']
ObjectId id
Set<ObjectId> to
Author author
String text
List<Comment> comments
Set<String> tags
Date postedOn
Date lastEditOn
}
class Comment {
Author author
String text
int thumbsUp = 0
int thumbsDown = 0
Date postedOn
Date lastEditOn
}
And the following code for serialization to JSON
render Message.findStreamFor( session.user, groups, 0, 20 ) as JSON
However, none of the embedded collections are being serialized. They are just missing. I've tried adding the following to my Config.groovy to make it deeply serialize by default:
grails.converters.json.default.deep=true
But that doesn't seem to change anything. I've seen the objects are populated from MongoDB in the debugger, but it just doesn't make it to the JSON serialized output. How can I fix this?
UPDATE
Ok I've figured out a bit more by debugging the code. Inside the DefaultGrailsDomainClass.getPersistentProperties() it doesn't return the collections as properties when called. And JSON serializer never visits them. On line 103 of DomainClassMarshaller is the call to getPersistentProperties which isn't returning all properties.
GrailsDomainClassProperty[] properties = domainClass.getPersistentProperties();
Seems like this is a bug! How has no one else ever found this?
You could to use GSON plugin. It didn't help me in a similar problem but it may help you.
This plugin was written to overcome nested object deserialization problem in standard Grails JSON converter, but it may also be better at serializing them.

Reading JSON thru web service into POJOs annotated for Hibernate

I am reading the following json through a web service. Is there a way to read the json into three appropriate POJOs? The POJOs are generated by hibernate and are used to communicate to the database.
Basically I need to read the person json into a Person POJO, the pets json into a set of Pet POJOs, and the toy json into a set of Toy POJOs.
The JSON
{
"person":{"first_name":"John", "last_name":"Smith"},
"pets":[{"species":"dog", "name":"Adama"}, {"species":"cat", "name":"Benton"} ],
"toys":[{"car":"corvet", "color":"black"}, {"action_figure":"hancock", "height":"1ft"} ]
}
The Web Service
#Post
public Representation readForm(Representation representation) {
try {
Person aPerson = …
Set<Pet> petSet = …
Set<Toy> toySet = ...
….
You can use xStream . You will have to create a VO having all 3 types of your objects as properties. Give them respective aliases and you will get all 3 types of objects in that VO. You can get them simply by calling their getters.

Mapping unpredictable keys from JSON to POJO

I am using the Jackson JSON library to map JSON streams into POJO's.
My JSON's keys have unpredictable names.
i.e
{
"Random_ID":
{
"Another_Random_ID":
{
"some_key": "value"
"some_key1": "value1"
}
}
...
}
I would like to map this request to a POJO (with the same structure), however the mapper will fail since there is no such setXXX (where XXX is a random_id - since i cannot predict the name).
What would be the best way to map this request to the corresponding object without manually parsing it with createJsonParser.
If names are unpredictable, POJOs are not the way to go.
But you can use the Tree Model, like:
JsonNode root = objectMapper.readTree(jsonSource);
and access it as a logical tree. Also, if you do want to convert the tree (or any of sub-trees, as identified by node that is the root of sub-tree), you can do:
MyPOJO pojo = objectMapper.treeToValue(node, MyPOJO.class);
and back to tree
JsonNode node = objectMapper.valueToTree(pojo);