We have a Java List of objects which is marshalled via JSON which is created by Jersey.
The List is called "rows". When there is data we have:
{"records":"1","page":"1","total":"1","rows":[{"id":"692334","cell":["ECS","D","201009","","0","ABCD","11","11","","201009"]}]}
When there is no data we have:
{"page":0,"records":0,"total":0}
How can we make Jersey include the rows field even if the List has a size of 0? What we want is:
{"page":0,"records":0,"total":0,"rows":[]}
Note that we are already using a JAXB ContextResolver to ensure the JSON is correct for a single row. Not sure if we can configure this resolver to solve our problem.
Use Jackson JAX-RS provider instead of alternatives (badgerfish/jettison), which does not do XML-to-JSON conversion. Missing array is most likely due to this conversion. There are multiple ways to configure this (jersey mailing list should have a few), and latest versions may expose it directly via Jersey API.
Maybe this helps you:
http://jersey.java.net/nonav/documentation/latest/json.html#d4e903
seems that some array problems can be solved by using something like this:
JSONConfiguration.mapped().arrays("yourArrayName").build()
At least it solves the issue, when the list contains only 1 item it's also formated as an JSON array.
I managed to solve JSON array "bug" in Jersey json library. Secret ingredient is previusly mentioned 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
Due to old project decisions, I work on a project that uses Jersey to connect to services that return XML data. Sometimes I could create the bean/pojo/whatever annotated with XmlRootElement and use webTarget.get(MyPojo.class)
However, if I try to do what I would do with, say, Jackson, and do webTarget.get(Map.class) I get the following error:
MessageBodyReader not found for media type=text/xml, type=interface java.util.Map, genericType=interface java.util.Map.
My case is, I have a XML that can have arbitrary fields whithin, so the ideal way for me to read it is to read a Map. Is there any way I can do that without having to rely in other libraries? I don't need to serialize data, only deserialize responses from the web services I connect to.
Found the answer, and it's kinda depressing.
According to the Unofficial JAXB Guide, you can't use a Map as a root element, unless you do a very ugly hack, described there. So, the solutions are:
Read as a String, and use Jackson to read a Map from the string.
Do the ugly hack.
Describe part of the schema in a bean, but the part that can have variable fields can be deserialized to a Map.
What serializer is Entity.json(T entity) using to serialize/deserialize objects? Is it somehow possible to use a custom serializer?
In my case the serialization is wrong because my object contains fields with the Guava Optional data type and absent values are returned as {"present":false} instead of null.
The JSON serializer isn't specified by JAX-RS, it depends on your configuration. For example, Jersey JAX-RS allows several (https://jersey.java.net/documentation/latest/media.html), including
MOXy
Java API for JSON Processing (JSON-P)
Jackson
Jettison
But a better solution is not to use Optional (either Guava or Java 8) for fields. See http://blog.joda.org/2014/11/optional-in-java-se-8.html
My only fear is that Optional will be overused. Please focus on using
it as a return type (from methods that perform some useful piece of
functionality) Please don't use it as the field of a Java-Bean.
Not directly solving your problem. I suggest you use Googles Gson as a parser. It is very flexible and configurable.
Tutorial
It also skips blank fields so the json size is not too large.
I'm parsing json with Gson but I'm struggling with the data I'm getting. This is part of an API out of my control (openFDA) so changing that might not be an option.
Here's the json I'm strugling with: https://api.fda.gov/device/event.json?search=device.generic_name:generator&limit=10
There are some fields that are not consistent, for example remedial_action. Sometimes it comes out like this:
"remedial_action": [
"Recall"
]
and in other results like this:
"remedial_action": ""
So it's either an array or a plain string. Is there a way to handle this? If not possible in Gson, any other json parsing library that can help?
I created my pojos here in case someone needs the code. There are a few files created from that and didn't want to spam them here. I can add them if needed.
Update: The bug has been confirmed and it's scheduled for a fix.
It is possible through GSON, by using a TypeAdapter.
Here are the initial steps I would use to do that:
Create a POJO that contains the array and the String. Let's call it RemedialAction.
In your original POJO, create an attribute of the new class.
Create a class that extends TypeAdapter<RemedialAction>.
Override the read() and write() methods and create the logic in them.
That should be a little hard to parse, though. Read this tutorial for more information.
Note: you can customize getRemedialAction() to give you only the valid return -- array or String.
As you could see from this question, the response that worldweather return is not quite pretty. They return array of current weather conditions (I try to understand why did they made it that way, there couldn't be more then one weather condition in a specific place, as far as I know...), so it breaks the unmarshalling via annotations,
#JsonProperty("current_condition")
private CurrentWeatherData currentWeatherData;
because Jackson actually awaits a collection or an array. Now, can I somehow to tell the unmarshaller to use the first array member, and if yes, how do I do that?
There is no such annotation. You will probably want a custom deserializer to handle this special case.
For Jackson 2.2 there will be support for separate Converters, which could work here (as they only work on Java objects). But since it is not yet released, custom deserializer is probably the way to go.
Hello Im trying to pass an array of objects from javascript to java , but how can this be done..??
I've found in some posts that they do this using a hidden input. Is this the only way?
I'm a bit confused. Please tell me what do I need to do to pass my array to the server? and which javascript files and jars do I need to add?
Thanks in advance.
You seem to want a completely baked-in solution. Not sure I can provide that, but here's what I'd do.
Indeed use a hidden input field in a form, where the value of the field is a valid JSON string. Send the form to your server, and in your servlet use a JSON Java library to parse the JSON string.
Here json-lib, gson or Jackson would do. In your case, I'd say json-lib would seem the easiest to use.
To generate the JSON string on the client-side, either use a framework or custom solution. For instance, jQuery has a serialize() function to serialize a form's fields to a JSON object directly, which you can then convert to string. Other frameworks provide similar functions.
To learn more about JSON, be sure to read the JSON Wikipedia entry and to visit the official JSON page (which also gives you a Java implementation of the JSON data-interchange format, though maybe not the most efficient one for processing a lot of data). To make sure your generated JSON is valid, you can use JSONLint.
If the objects are simple enough, you can encode your array as a JSON string. Java has libraries to encode and decode JSON.