Non flushable javax.json.JsonObjectBuilder
You do know how to handle Json objects in Java, right? If you don’t, just pretend you do and check out the javax.json API introduced in JavaEE 7.
Since JavaEE 7, this is the official, standardized way of dealing with Json in Java. Even if you develop a desktop application or a library, you can use the API by pulling in the implementation with “runtime” dependency scope.
In this post I’m going to illustrate the importance of interfaces, by showing you how I solved an annoying problem with this specitifaction.
You’ve probably used this API too, most likely for parsing responses from a REST endpoint. There, you simply built a JsonObject from the response’s InputStream and used it later only to read data from it, since JsonObject is immutable. Something like this:
or, you simply built a JsonObject, to send to a server with a POST request:
In neither of these occasions, the flaw I’m talking about is not visible: JsonObjectBuilder.build()
flushes the builder.
So, in the car
example above, if you would call build()
multiple times, only the first would output the desired JsonObject; the following calls
would result in an empty object. See this SO question about this “strange behaviour”.
Why is it a flaw? Because otherwise, you could elegantly use JsonObjectBuilder as the skeleton of any “mutable” implementation. It is a prefect in-memory storage. For instance, I’m using a JsonObjectBuilder to back a mock HTTP server. This basically means I have a bunch of classes which mimic the real HTTP API without actually making calls to any server. Instead, all the data is read/written from/into a JsonObjectBuilder. The build() method is called at every read operation and thus it is very inconvenient to have the builder flushed afterwards.
So how do you solve this issue? The first thing you do is start looking into different implementations. You try both Glassfish and Redhat to see that they behave the same. Bummer. Since there is no other way, the obvious solution is to write a global static method which takes the JsonObjectBuilder, builds the JsonObject and then, iterating over the JsonObject, adds the attributes back in the builder; something like this:
This should work fine, except you will soon realize that all your code is poluted with calls to this static function. Wherever the build()
method is called, you have to also call this function. Good luck debugging if you forget to use it somewhere. And you (or one of your new colleagues) will, for sure. Besides, static methods are always an ugly solution because they
make our code more procedural.
Then, maybe you realize that javax.json.JsonObjectBuilder
is an interface and that you can implement it to have any behaviour you need.
So what? You are now going to reimplement everything those smart guys from Oracle or Redhat already implemented? No, of course not. Check this out:
Do you see the advantages of having a standardized API with clear interfaces? Now, the only difference in your code will be that, instead of instantiating your builder like this:
you will do it like this:
And it will work like a charm.
Finally, I am aware (and you should be, too) that this is really basic OOP. But at the same time, I am ready to bet quite a fair amount that most developers would come up with the second solution or maybe even think of switching to some library from Google or what not. A lot of developers simply do not take advantage of such simple concepts as interfaces.