I used Jersey to create a JAR-RS Web Service that responds with JSON formatted data.
When a request arrives, with the #Path annotation, a method captures the request processes it and return something.
For example, I created a JSONArray object called jsonArray in the method that handles the request. I can use return jsonArray.toString(); to get a String and send it back. I can also use return jsonArray and JAXB(the annoation #XmlRootElement in the JSONArray class and #Produces({ MediaType.APPLICATION_JSON}) in the method) to automatically serialize the object in JSON format.
I would like to know what is the difference between manually sending back a String and automatic serialization by using annotations.(Performance?)
No, there is no output difference. The main difference is that return jsonArray can be considered to be more readable (especially for other programmers), while return jsonArray.toString() is more explicit. The problem with the former is that things are more obscure as someone reading your code needs to understand that something that gets the jsonArray object silently serializes it.
Another difference between approaches is that letting the framework do it guarantees that eventual updates in the framework will be reflected in the way things get serialized. The toString() method was not originally designed to provide a serialized view of an object, which can later be used to get the object back, but to simply provide a textual (even incomplete) representation of the object.
If the class you are using does not provide serialization or if the provided serialization does not generate JSON (or whatever format you want) correctly, you can always create your own serialization. Wrap the object inside of one belonging to a class that you defined and make such a class serializable. Then provide the following methods:
private void writeObject(ObjectOutputStream out) throws IOException;
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;
And, yes, they should be private. See more here: Discover the secrets of the Java Serialization API
Related
The situation is like this:
I get a json that can be one of several classes. All possible classes are combined by one parent.
public class Response implements Serializable {}
I would like to do it beautifully something like:
Response response = GSON.fromJson(content, Response.class);
RegisterPreAuthResponse registerPreAuth = (RegisterPreAuthResponse) response;
Not of course I can't do that. Since I get a ClassCastException
I had an option to make a loop with ignoring ClassCastException and iterating over the children to define the class.
Or make a JSONObject and define the fields that came in and then create a class.
But I would like to find the best way.
GSON does not know anything about java types, it only tries to parse input string and map it to class you have requested.
If you want something like dynamic mappings it will be ugly since you will have to obtain information what kind of response it is. For example have "class" : "packet.Class" in your response body / headers.
But this is really bad practice and should be avoided.
I see that you have content (JSON response) from some service so maybe you can determine in your code type of response by kind of service you have called?
I am getting objects of different type as a parameter into different service APIs.
Example APIs:
void API1(Object1 obj1);
void API2(Object2 obj2);
On receiving the APIs, I convert objects to JSON type and store at a specified location. Another poller polls for the stored location and tried to convert it to object type using Gson.
One way, I can think of is to create a RequestWrapper containing objects of all type (ex. Object1, Object2 etc.) and populate the correct variable while storing the data.
On receiving end, we can convert the object to RequestWrapper object and check for the populated object.
As you can see, this requires additional object of 20+ variables and most of them will be null. Also, multiple if-else checks while converting it to correct type.
What could be the best way to achieve this in object oriented way, if any?
At a basic level, it would seem there are two approaches to getting the data type of a serialized object that came from a client.
Make the client tell you.
Figure it out for yourself.
A couple ways I can think of to make the client tell you:
Add an API for each distinct data type.
void API1(Foo obj1);
void API1(Bar obj2);
void API2(Foo obj1);
void API2(Bar obj2);
Require the client to include it in the serialized form.
{"class":"myPackage.MyClass"}
A couple ways I can think of to figure it out for yourself:
Pre-parse the JSON string for some unique identifier (i.e. determine the type before deserializing).
if (jsonString.contains("foo")) {
Foo foo = gsonInstance.fromJson(jsonString, Foo.class);
}
The aforementioned wrapper approach (i.e. determine the type after deserializing).
I don't know that any approach is particularly object oriented, but then how object oriented is serialized data to begin with?
JSONObject class of package org.codehaus.groovy.grails.web.json does not implement Serializable.
I want to make this object serializable as I am using session replication among application servers and JSONObject gets saved in session.
I have two options to achieve this:
Subclass JSONObjects that implements Serializable.
use toString() method on JSONObject object while saving this object in session.
Can anyone please suggest which one of two options should I use and what is the reason?
I think the toString method is what's intended to be used here. That method already returns the JSON text of the object, which is suitable for transmitting or storing.
You don't need to serialize JSON, it is already in a store-able form(sort of the whole point of JSON). Grails has JSON parsers and "slurpers" all ready to use for you. So just store the JSON data as a string and use a parser on it to read it back out of the file.
I have been using the jackson implementation of the json protocol in my own little project, and it has gone just fine a while now until I decided (for the first time) to serialize a stateless object.
I know that might sound weird, why would I want to send a stateless object? What I serialize is requests for a server, and this particular one conatins no fields, just code for an instruction on the server side. My model can take any ClientRequest implementation and call it's perform() method. I want it to work even though the request comes without fields.
Code looks like this:
public class GetWallInputsRequest implements ClientRequest<List<WallInput>>
{
#JsonCreator public GetWallInputsRequest()
{
}
#Override public ServerResponse<List<WallInput>> perform()
{
return new WallMessageResponse( Wall.WALL.getInputs() );
}
}
I get JsonMappingException: No serializer found for class GetWallInputsRequest.
Google does not help me, which makes me wonder if I'm just being stupid. Sadly I don't see a way out of this.
I solved it after a lot of brute force attempting different things. And by solved it I mean not figured it out but made it work. By adding the line:
#JsonAutoDetect(getterVisibility=JsonAutoDetect.Visibility.NONE)
above the class declaration it seems to work out. Why this is necessary I don't know, but now It sends an empty json string instead of crashing.
The documentation says
Value that indicates that no access modifiers are auto-detectable: this can be used to explicitly disable auto-detection for specified types.
Since your class doesn't include any explicit notations to tell Jackson that there's a field or method to serialize, it determines that there is indeed nothing to look for. Without this, I presume, it's going to expect something, as suggested in the documentation quoted.
http://jackson.codehaus.org/1.9.0/javadoc/org/codehaus/jackson/annotate/JsonAutoDetect.Visibility.html
I was going through a blog and one question came to my head. Is it possible to overwrite the way ObjectOutputStream is writing.
Let's say i am writing to a file out.dat i.e.
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(new File("C:\\out.dat")));
out.writeObject(o);
When i opened the file out.dat in Notepad++, i saw the binary data. Which makes sense. What if, I would like to customize the way this data is being written. Lets say i want my out.dat file in JSON format (Thats just an example, It could be any other format). What method should i overwrite to do this?
You'll be able to do what you want by implementing Externalizable and overriding the writeExternal and readExternal methods. See http://download.oracle.com/javase/7/docs/platform/serialization/spec/output.html#3146 for details.
Note that it will allow customizing the output of the serialization of one object, but not the format of the whole stream. You will thus find your JSON string inside other binary data.
i think that you shouldn do it, because this format is used to keep comunication between tiers (work with distributed objects on a network). What you can do is just create a handler that store your object in a file using your pretty format.
You can make your object implement Externalizable and have full control over serialization. Use e.g. google-gson for JSON when implementing the readExternal / writeExternal methods.
In your scenario , where you are looking for a custom serialization mechanism , I would recommend that you implement Externalizable interface and provide implementations of methods
public void writeExternal(ObjectOutput out) throws IOException
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
Its entirely up to you how you want to serialize in this case.
I'm pretty sure that java does not have internal support for serializing to JSON. In my opinion your best bet is to create a interface for a getting the JSON and have any objects you want serialized to JSON implement this interface:
public interface IJSONSerializable{
public String getSerializedForm();
}
And then use a basic FileOutputStream to output since (as I understand it) the ObjectOutputStream is used to serialize a object to binary and does not have inherent support for JSON.
Other Thoughts
If you choose to go this way you could write a helper class for writing out things such as a property and a value.
Well Java itself has no built-in support for JSON serialization, but then I'm sure you can find frameworks that do that - or just write it yourself for simple classes.
So for any class you want to serialize in JSON format just overwrite
private void writeObject(java.io.ObjectOutputStream out)
throws IOException
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException;
Shouldn't be too hard if there's some JSON framework out there that gives you the data of one instance in string format and vice versa.