Deserialize Json with inconstant field to POJO in Java - java

Is there a possibility to create POJO class in Java to which this
Json can be deserialized?
{
"name": "value",
"random-value-01" : {
"constant-field-00":"value_00",
"constant-field-01":"value_01"
},
"random-value-02" : {
"constant-field-00":"value_02",
"constant-field-01":"value_03"
},
...
"random-value-XX" : {
"constant-field-00":"value",
"constant-field-01":"value"
},
}

If all of your random-value-x JsonObjects have the same format (i.e. the two constant fields are the same for each), then you could always have something akin to:
class RandomValue {
private final String constantField00;
private final String constantField01;
// ... Constructors, getters, etc.
}
class Pojo {
private final String name;
private final Map<String, RandomValue> randomValues;
// ...
}
If they're ordered (i.e. they're all the same random-value, like property-01, property-02, etc.) then you could also have the Map be a List (or Set, etc.) of your RandomValue elements.
If, on the other hand, the constant-fields are all random keys as well, then you're probably stuck with something more like:
class Pojo {
private final String name;
private final Map<String, Map<String, String>> additionalInfo;
// ...
}
Where the keys to the additionalInfo Map are your random-value-xs, and the values are a Map of String keys (constant-field-0xs) to String values (values).

This is not an answer as such, but may pique one's interest on the general topic.
For those interested in a different approach to JSON, one can look at the ITU's ASN.1. Think of it as a bit like Google Protocol Buffers, but with a whole load of different wire formats (including JSON, XML, and a whole load of binary wire formats with varying properties). Basically there's a wire format for every occasion and purpose.
This can be extremely useful sometimes. If you want to ship data around a distributed system, and parts of that system are, say C on a microcontroller at the end of a low bandwidth radio link, whilst other parts are Java on a server, then you can encompass all of your system messaging in a single schema (which acts as a the single point of truth). From this you can (depending on the tools you use) generate plain old objects in C, C++, Java, C#, and even ADA, VHDL. Python is a notable omission (there's Python modules to do code-first ASN1, which kind of misses the point).
It's use of JSON as a wire format is a relatively recent addition to the standard, but some of the commercial tools support it. For those who really need it, it can be a very useful tool.
From the point of view of this particular question, ASN.1 and the tools that support JSON as a wire format is not useful; you cannot take arbitrary JSON and automatically generate a schema that can be compiled to classes. Where it is useful is in a fresh project, where you want to make it easy for other languages / platforms to consume or generate your data.
I have looked for decent C# class generators that consume JSON schemas; unfortunately the best one out there didn't deal with oneof. However the tools I'm using for ASN.1 (which has the equivalent CHOICE) do generate complete classes in C#, Java, C/C++. So I'm in this amusing situation where I have an ASN.1 schema that I compile (in this particular project) to C# and C, and it deals with JSON, XML, and the binary wire formats. The generated classes are smart enough to do their own validation - I don't have to pass the JSON through a JSON schema validator.
JSON schemas and ASN.1 schemas are broadly comparable in terms of the detail one can put into a specification. Similarly ASN.1 schema and XSD XML schema are broadly equivalent (there's even an official standardised translation between the two languages). The benefits I've seen of using ASN.1 schema instead of JSON or XSD schema is that the tools (especially the commercial tools) seem to be significantly more thorough than the class generators typically associated with JSON and XSD schemas (e.g. Microsoft's xsd.exe sucks). This has had a knock-on positive benefit for systems integration, maintenance, being agile with data definitions, etc.

Related

Android Firestore limitations to custom object models

I am migrating my app to use Firebase Firestore, and one of my models is very complex (contains lists of other custom objects). Looking at the documentation, on how to commit a model object as a document, it looks like you simply create your model object with a public constructor, and getters and setters.
For example from the add data guide:
public class City {
private String name;
private String state;
private String country;
private boolean capital;
private long population;
private List<String> regions;
public City() {}
public City(String name, String state, String country, boolean capital, long population, List<String> regions) {
// getters/setters
}
Firestore automatically translates this to and from and document without any additional steps. You pass an instance to a DocumentReference.set(city) call, and retrieve it from a call to DocumentSnapshot.toObject(City.class)
How exactly does it serialize this to a document? Through reflection? It doesn't discuss any limitations. Basically, I'm left wondering if this will work on more complex models, and how complex. Will it work for a class with an ArrayList of custom objects?
Firestore automatically translates this to and from and document without any additional steps. How exactly does it serialize this to a document? Through reflection?
You're guessing right, through reflection. As also #Doug Stevenson mentioned in his comment, that's very common for systems as Firebase, to convert JSON data to POJO (Plain Old Java Object). Please also note that the setters are not required. If there is no setter for a JSON property, the Firebase client will set the value directly onto the field. A constructor-with-arguments is also not required. While both are idiomatic, there are good cases to have classes without them. Please also take a look at some informations regarding the existens fo the no-argument constructor.
It doesn't discuss any limitations.
Yes it does. The official documentation explains that the documents have limits. So there are some limits when it comes to how much data you can put into a document. According to the official documentation regarding usage and limits:
Maximum size for a document: 1 MiB (1,048,576 bytes)
As you can see, you are limited to 1 MiB total of data in a single document. When we are talking about storing text, you can store pretty much but as your array getts bigger (with custom objects), be careful about this limitation.
Please also note, that if you are storing large amount of data in arrays and those arrays should be updated by lots of users, there is another limitation that you need to take care of. So you are limited to 1 write per second on every document. So if you have a situation in which a lot of users al all trying to write/update data to the same documents all at once, you might start to see some of this writes to fail. So, be careful about this limitation too.
Will it work for a class with an ArrayList of custom objects?
It will work with any types of classes as long as are supported data type objects.
Basically, I'm left wondering if this will work on more complex models, and how complex.
It will work with any king of complex model as long as you are using the correct data types for your objects and your documents are within that 1 MIB limitation.

Easier way of converting Json to Java (Jackson)

I am receiving massive json objects from a service and so far i've been creating POJOs to match the json that comes in.
However, this is getting far too tedious as with every different service I hit I have to build 15-20 new model classes to represent the new service i'm hitting.
In short, what i'm looking for is a way to get a value I need from a neested object in the json as below (sorry for format):
random1 {
random2 {
arrayOfRandoms
}
random3 {
random4 {
random5 {
someValueIWant
}
}
}
}
so in this case I want random5s someValueIWant object. I want to get it without creating the models for random1/3/4/5 as i've been doing this whole time.
I should mention that I use Jacksons ObjectMapper to turn the json into java objects.
Hope this makes sense.
You could experiment with this online pojo generator:
http://www.jsonschema2pojo.org/
It will generate java classes from plain json (or json schema) and even add jackson annotations.
Make sure you check "Allow additional properties".
It requires valid json as input, so don't forget double quotes around fields names and values
If you find yourself doing that often, there's even scriptable versions and maven plugins.

Converter from Json into groovy CODE?

It's a kind of odd question for an odd situation. I have a large JSON structure which I would like to represent in running groovy code. I need groovy objects that mirror the same structure as the JSON objects.
As to be expected a web search mostly returns results with groovy/json runtime conversion stuff, but nothing about things that output groovy code.
You might think this lazy but really it is a massive JSON structure! A converter would save days!
You can use Groovy's own JsonSlurper to parse JSON objects:
import groovy.json.*
def json = '{"name":"john", "surname":"doe", "languages": ["groovy", "python"]}'
def obj = new JsonSlurper().parseText(json)
assert obj.name == "john"
assert obj.surname == "doe"
assert obj.languages.containsAll("python", "groovy")
Of course the class is untyped: it's only known at runtime. If you want it to be typed, you can write a code which writes the code based on an example (since a json schema may be rare).
EDIT: if you want to generate the model classes code, you can try JSONGen, which "parses JSON to create client side source files to model the JSON data structure". I'm not aware of a solution for Groovy, but since java-groovy integrations is seamless, it shall work fine.
If you want a Groovy representation of your JSON, you can get that via the built-in JsonSlurper. This will give you Java Maps and Lists of data you can work with.
You can populate more specific, custom objects you've written to represent your JSON entities using the (3rd party) Jackson's data binding functionality (see this question as well).
Try using a JSON parser like this one. According to its documentation you just need to do
JSON.parse
to deserialize the data

XML data types specification

While there is plenty of documentation about XML document structure, there are very few links to how non textual data (eg. integer and decimal numbers, boolean values) should be managed.
Is there a consolidated standard? Could tell me a good starting point?
POST SCRIPT
I add an example because the question is actually too generic.
I've defined a document structure:
<rectangle>
<width>12.45</width>
<height>23.34</heigth>
<rounded_corners>true</rounded_corners>
</rectangle>
Since I'm using DOM, the API is oriented to textual data. Say doc is an instance of Document. doc.createTextNode("takes a string"). That is: API doesn't force towards a particular rapresentation.
So two question arise:
1) saving bolean true as 'true' instead of uhm, 1/0 is a standard?
2) i have to define simple methods that write and parse from and to this string representations. Example. I may use java wrappers to do this conversion:
Float f = 23.34;
doc.createTextNode(f.toString());
but does it adhere to the xml standard for decimal numbers? If so, i can say that a non-java programs can read this data because the data representation is xml.
why not jaxb
This is just an example, my xml is made up of a big tree of data and i need to write and read just a little part of it, so JAXB seems not to fit very well. Binding architecture tends to establish a tight copuling between xml structure and class structure. Good implementations like moxy let you loosen this coupling, but there are cases in wich the two structures simply don't match. In those cases, the DTO used to adapt them would be more work than using DOM.
Of course, there are dozens of official standards related to core XML. Some of the important ones:
XML schema 1.1 overview
XML schema 1.1 - datatypes ('XSD')
XML schema 1.1 - structures
Core XML overview
XML 1.0
XML 1.1
Further specification like XPath, XQuery are available at www.w3.org/standards/xml/. As you tagged this question with java you may be interested in JAXB as well, which defines a standard approach for mapping XML to Java and vice versa.
You can leverage the javax.xml.bind.DatatypeConverter class to convert simple Java types to a String that conforms to the XML Schema specification:
Float f = 23.34f;
doc.createTextNode(DatatypeConverter.printFloat(f));

Accepted practice for converting an Object to and from a String in Java?

What is the commonly accepted method for converting arbitrary objects to and from their String representations, assuming that the exact class of the object is known ? In other words, I need to implement some methods similar to the following:
public interface Converter {
/**
* Convert this object to its String representation.
*/
public String asString(Object obj);
/**
* Take the String representation of an object produced by asString,
* and convert it back to an object of the appropriate class.
*/
public Object asObject(String stringRepresentation, Class clazz);
}
Ideally, the solution should:
Use the object's built-in toString() functionality, if possible. Thus, converter.asString(new Integer(5)) should return "5", and converter.asObject("5", Integer.class) should return an Integer with the value of 5.
Produce output that is human-readable whenever possible.
Deal with all common Java data types, including java.util.Date .
Allow me to plug in conversion functionality for my own, custom classes.
Be reasonably light-weight and efficient.
I understand that there are any number of ready-made solutions that do this (such as Google's protocol buffers, for example), and that I could easily implement a one-off solution myself. My question is not, "how do I solve this problem", but rather, "which one of the many ready-made solutions is the current industry standard ?".
My question is not, "how do I solve this problem", but rather, "which one of the many ready-made solutions is the current industry standard ?".
None of them have emerged as defacto standard.
The closest you can get it "default" XML serialization mechanism which BTW sucks if you pretend to write them by hand ( and It is good enough when you use them automatically )
The next thing closest to an standard and that would be for daily usage, would be JSON to Java, but, well, you know, it is not Java Java
I would vote for Json as well and then particularly Gson. It handles generic/parameterized objects very well.
Alternatively, you can also write a generic object converter which does all of the needed conversions with a little help of reflection, such as this example. But if your "API" require that this converter is to be published as an interface to the enduser, then I would only suggest to replace
public Object asObject(String stringRepresentation, Class clazz);
by for example
public <T extends Object> T asObject(String stringRepresentation, Class<T> clazz);
so that one doesn't need to cast it afterwards.
You can look at the svenson library, it converts java objects to json. Its pretty quick and uses annotations to introduce custom converters.
http://code.google.com/p/svenson/
Not long ago I would have proposed an xml serializer, but after playing with couchdb for a couple of days, I serve a new master... json.
Although it is tempting to use or attempt to implement "toString()" as a reversible operation, the purpose of "toString()" is to generate a user-friendly and easily understandable representation of an object, and this goal is often at odds with including enough state information to truly restore the original object.
If you are looking to persist an object, using XML, JSON, or binary serialization is probably the best way to go. The "toString()" function should report a human-friendly representation of an object (e.g. "5", "(3,0,2)", "5+6i", "{1, 2, 3, 4, 5, 6}", "{x => y, z => 3}", etc.). Even in cases where it is possible to completely restore the object from the generated string, the time to write a function to parse each type of (potentially unstructured) text is best conserved via automated XML persistence in favor of time to write the actual application.
I agree with Oscar that XML might be the preferable form here, if you can tolerate large uncompressed file sizes. To elaborate on his answer, in my experience if you write a fairly straightforward utility class you can serialize your objects into XML with not too much work. To read them back, I would recommend Apache Digester which does a great job of rule-based interpretation.
I would only opt for other file formats if I cared about performance or file sizes, though I eprsonally in most cases prefer the flexibility of XML.

Categories

Resources