I have a class with 2 values: val1 and val2. I am sending val1 to register (create) API and val2 is auto filled by API itself. I do not want to send val2 while calling create API and that API is not designed for handling unwanted values.
In short I want to ignore val2 while I call create API but I want it while I call get API.
The code that I have right now creates JSON including both the values assigning null to val2. This causes that API to throw an exception.
Is there any easy way of doing it (java /groovy)?
Is there any easy way of doing it (java /groovy)?
Not 100% sure I'm understanding your need. I believe it depends on what json de/serializer you are using. For example, using Jackson we do:
#JsonIgnoreProperties(ignoreUnknown = true)
#JsonTypeName("account")
public class Account {
I believe this allows us to load in objects with a ton of extra json fields into objects without corresponding java fields. To quote from the javadocs:
Property that defines whether it is ok to just ignore any unrecognized properties during deserialization. If true, all properties that are unrecognized -- that is, there are no setters or creators that accept them -- are ignored without warnings (although handlers for unknown properties, if any, will still be called) without exception.
Related
I am using Jackson api for serialization and deserialization. My application is low latency application, so my target is to avoid creation of objects.
For class :
Class Quote {
int instrument;
Double bidPrice;
}
It works fine if valid bidPrice or null is present for quotes and serialization or deserialization works fine.
However, java is creating lot of objects using Double.valueOf due to autoconversion.
I tried using ObjectPool concept using MutableDouble , so that it returns the double value or null value. however, while assigning the types, It again reverts to same problem of : Double.valueOF.
In summary, how I can serialize or deserialize double value as NULL or valid value without creating wrapper objects.
Please note that I am fine to create initial set of objects for storing values ,and can not change the contract due to external vendor protocol.
any suggestions related to this problem is highly appreciated.
It seems that GSON silently ignores when a JSON string contains field names that don't match the target POJO class. One solution outlined here suggests to use annotations to mark "required" fields to have GSON fail when de-serializing strings that don't contain fields.
But we defined that our POJOs must be "exact" matches (when we allow for incoming objects to be null, they must be declared as Optional field in the POJO - and we have a special type adapter that turns nulls into Optional.empty() instances). Therefore all fields in the POJO are mandatory. And null isn't a valid value.
Following the guidance in that question I linked to, it seems that the only way of having gson fail while parsing: to do a full "deep reflection" scan of the object created by de-serialization process and check if any of the Optional fields are null.
Or maybe - I am missing something and there is an easier way to have gson tell me when our JSON strings contain bad field names?
( background: we just ran into a problem because of wrong field name deep down in a nested structure - leading to null objects where we didn't expect them )
Turns out: this "deficiency" is really a core design point of gson: it is a JSON parser. Validation is not within the scope of gson.
Therefore the "correct" answer is to use java bean validation annotations and to put some implementation framework (for example the hibernate validator or apache bval) in place.
Alternatively, it is possible to register a special type adapter when creating the gson instance. This type adapter uses reflection to override an internal map with a bit of checking code - allowing for a relatively "clean" solution which leads to gson throwing an exception when running into "unknown" fields. ( thanks to Andy Turner for pointing to the corresponding github issue tracker entry --- code can be found there)
I have a RESTful web service that provides JSON that I am consuming. I am using Spring 3.2 and Spring's MappingJacksonHttpMessageConverter. My JSON looks like this:
{
"Daives": {
"Daive": {},
"Daive": {},
"Daive": {},
"Daive": {}
}
}
Now everything I have read seems to indicate that this JSON should be refactored to an array of JSON Daives. However, this is valid JSON so I want to make sure that I am thinking correctly before going back to the service provider to ask for changes. In the format above, I would have to know ahead of time how many Daives there are going to be such that my DTO accounted for them. The handy dandy Jackson mapper isn't going work with this kind of JSON setup. If the JSON was altered to provide and Array of JSON Daives, I could use a List to dynamically map them using Spring/Jackson.
Am I correct? Thanks :)
According to this thread, the JSON spec itself does not forbid multiple fields with the same name (in your case, multiple fields named "Daive" in the object "Daives").
However, most parsers will either return an error or ignore any value but the last one. As you said, putting these values into an array seems much more sensible; and indeed, you'll be able to map this array to a List with Jackson.
Currently I have a class setup to be processed as an autobean:
public interface Asset extends Hit {
String getGuid();
String getHitType();
Map<String,Serializable> getMetadata();
}
I tried using Object instead of Serializable:
Map<String,Object> getMetadata()
but this seems to blow up when trying to access data (because it's not 'reified').
The Metadata map may contain other maps, strings, ints, etc. How do I retrieve data from an inner map of that metadata object?
Currently, if I call asset.getMetadata().get("title"); this returns a SerializableAutoBean and performing toString() or String.valueOf(obj) on that object returns the in memory object information and not the actually string value.
Can an AutoBean object be this dynamic, or do you specifically have to define every field?
AutoBeans aren't "dynamic" in the Java generics or RTTI sense.
In GWT, all types have to be known at compile time for anything which is auto-generated (which includes AutoBeans). This places restrictions on your designs which don't allow you to take full advantage of Java's language features (specifically, generics and other RTTI features). So, AutoBeans are not dynamic in the RTTI or Java generic sense. However, AutoBeans are simply a low-level way of wrapping your data, and you still have access to the data by using Splittables!
As stated in the previous comments, you can use Splittables for the parts of your JSON object whose type is not known at serialization/decode time. Sure, it would be nice to have everything happen at once, but nothing is stopping you from performing some post-processing on your data objects to get them into your desired state.
A really good way for someone to "Grok" what is going on with AutoBeans (and anything else which is autogenerated) is to look at the resulting generated code. The default location for maven is: ${project.build.directory}/.generated.
If you look in there after you've compiled, you should find the code which the GWT compiler produces for your AutoBeans.
I use Jackson and want to check that input JSON string doesn't contain duplicated properties like:
{"a" : 1, "a" : 0}
Following Jackson fragment process input string without any errors and even return value:
JsonNode jsonSelect = mapper.readTree("{ A : 1, A : 0}");
System.out.println(jsonSelect.getFieldValue("A")); // prints 0
Does I have a chance to validate duplicates via Jackson?
P.S. Does JSON format support duplicated properties at all? I didn't find any restrictions about it in specification. Also org.json.JSONObject throws an exception for duplicates that doesn't give me an answer - is {"a" : 1, "a" : 0} well-formed according to standard.
JSON specification indicates duplicates are not consider valid, but parsers are not required to do anything about them. From practical perspective, keeping track of all seen properties adds overhead, which may not make sense at streaming parser level.
As to Jackson, it used to have duplicate detection at data binding level, but I think that is not enabled at this point. It could be added fairly easily when dealing with Maps.
If this is something you would want, filing a feature request or asking on user list might make sense (esp. to see if others would want this feature too, making it more likely to get added soon).
If all you want to do is just validation, you could create a Map subclass, make it throw exception on duplicate. Or, just set a flag in sub-class that you can check if you prefer.
JSON does not support duplicated properties. So if your input is guaranteed to be valid JSON you don't have to check for them.