I am developing an API that reads data generate by another program. The data is in a json format and I want to use Gson to read that json data into a json object and also report any unused data that hasn't been specified in the class. For example, I have this json:
{"Event": "ChatMessageSent", "Message": "This is a test message!", "Time":1628466226}
Now, the class only has the Event String and Message String, so it will only store that data. My question is how can I set up my POJO Class or get Gson to also return the Time data in a special method that returns all unused data, so it can be sent to a debug log for throwing a warning for unused data. Since the data may change at any version, I need to create a logging system that tells me if the API missed some data.
Any pointers are much appreciated, thanks in advance!
How about creating a custom GSon deserializer for the fields you need. You could look into TypeAdaptor.
Related
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.
I use the jersey/jackson stack to address a neo4j database via the REST api, but I have some issues how to interpret the result.
If I read the node by its ID (/db/data/node/xxx) the result can be mapped to my DTO very easy by calling readEntity(MyDto.class) on the response. However, usage of internal IDs is not recommended and various use cases require to query by custom properties. Here cypher comes into play (/db/data/cypher).
Assuming a node exists with a property "myid" and a value of "1234", I can fetch it with the cypher query "MATCH (n {myid: 1234}) RETURN n". The result is a JSON string with a bunch of resources and eventually the "data" I want do unmarshall to a java object. Unmarshalling it directly fails with a ProcessingException (error reading entity from input stream). I see no API allowing to iterate the result's data.
My idea is to define some kind of generic wrapper class with an attribute "data", giving this one to the unmarshaller, and unwrapping my DTO afterwards. I wonder if there is a more elegant way to do this, like using "RETURN n.data" (which does not work) or something like this. Is it?
You should look into neo4j 2.0 where return n just returns the property map.
I usually tend to deserialize the result as a nested list/map (i.e. have ObjectMapper read to Object.class or Map.class) structure and grab the data map directly out of that.
There's probably a way to tell jackson to ignore all the information around that data field
If you want to have a nicer presentation you can also check out my cypher-rs project which returns only the data in question, nothing more.
I have a data structure class and incoming JSON data. I use the fromJson(jsonData, MyClass) method to deserialize the data into the class. The incoming JSON data varies and sometimes certain values are not sent.
I would like to be able to determine which values are not sent from those that are sent but specifically set to null. Initializing the fields in my data structure class does not seem to help because even if they are not sent in the raw JSON data, they are set to null during the fromJson() method it seems. I also could not seem to get this to work with a deserialization exclusion strategy.
Any help would be appreciated.
I am using GSON to decode JSON strings that are returned from our server. I haven't had any problems, until I ran into this one particular JSON return from the API. The return is in the following format:
"success":1,"errors":[],"data":{"524":{"id":"524"}, "525":{"id":"525"}}
For the other returns I had data as an array of a class of my own creation, but for this return it says that it is an object and not an array. So how should I format my class?
***edit: What I am having trouble with is that the '524' and '525' fields are not static names. They are dependent on what the user's credentials are. There could be fields 323, 324, 325 or a single one 123. It all depends. How would I be able to handle this dynamically?
SOLVED*
What I had to was make 'data' a <String, Object> hashmap in my custom class. Then after the first decoding, I turned 'data' into an array of type Object []. Then for each Object[i], I converted it into a JSON string. After that I used gson.fromJson() to convert it into what I had originally intended for it to be.
If the API is giving inconsistent results and you can't find a reason on your end why it is doing so, one option is to parse the object into a GSON JSONObject o = gson.fromJson(String) and then convert the data to a list if it is not one already by doing o.getElement("data").isList(), etc..
When this is complete, you can then create the object via gson.fromJson(JSONObject,Class). The alternative is to have two classes, one for each instance, but this seems sloppy if this is the only reason to have two different classes.
GSON is correct. From server reply data is object with two members that are objects also. To be array data should have square brackets [] instead of curly brackets {}. More about JSON format here.
Server format was changed or you tried another API version or someone made bug on server side.
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.