I am trying to deserialize a json object into a java bean.
The main issue I am facing is that I'd like to treat the field object of the json string as a plain string, even if it contains a potentially correct json object.
The json structure is like this:
{
"type":"user",
"object":{
"id":"1",
...}
}
How can i tell gson to ignore the object value so that it doesn't get deserialized into an object? I'd like it only to be mapped to a plain String field in my bean so that I can dispose a proper deserialization for it, once I got the type from the type field.
Just declare it as of type JsonObject
class ExampleJsonModel {
#SerializedName("type")
public String type;
#SerializedName("object")
public JsonObject object;
}
I don't know if your problem is solved. I ran into a similar question and here it is how I worked it out:
JsonDeserializer allows you to make you own adapter to deserialize that **:
class JavaBeanDeserializer implements JsonDeserializer<JavaBeanObject>() {
public JavaBeanObject fromJson(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
// return JavaBeanObject built using your logic.
}
You've to register JavaBeanDeserializer to Gson object when building it:
Gson gson = new GsonBuilder().registerTypeAdapter(JavaBeanObject.class, new JavaBeanDeserializer()).create();
Related
There is already data present in S3 Bucket which needs to be processed.
Data Follow this particular Schema
{
"serviceId": "9e148371a96b9054e689d3669998ef54ff11cdd3cad9dfa395e4da4c5a50cbc4",
"serviceVersion": 2
}
POJO Classes
abstract class Service {
String serviceId;
int serviceVersion;
}
ServiceA extends Service {
String fieldX;
}
ServiceB extends Service {
}
Code
USing Gson to desrialize this data
Gson gson = new Gson();
String data = "{\n" +
" \"serviceId\": \"9e148371a96b9054e689d3669998ef54ff11cdd3cad9dfa395e4da4c5a50cbc4\",\n" +
" \"serviceVersion\": 2\n" +
"}";
Code fails with exception
Failed to invoke public com.*.transportation.*.Service()() with no args
How do i deserialize this data ?
Registering CustomType Adapters won't help either, since Data is already deserialized, and no Type information is available.
Only solution i can think of here, is to create customerTypeAdapter and decide the Type of Concrete class on the basis of
#Override
public Service deserialize(JsonElement jsonElement, Type type,
JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
JsonObject jsonObject = jsonElement.getAsJsonObject();
if (Object.nonNull(jsonObject.get("fieldX") {
return jsonDeserializationContext.deserialize(jsonElement,ServiceA.class);
}
jsonDeserializationContext.deserialize(jsonElement,ServiceB.class);
}
Please suggest some the alternative, if this can be solved in a better way?
I have provided this as an example, but the actual object is very large and consists of too many nested interface/abstract classes.
Data is already present in S3/Local Storage and no _type information is present.
I am trying to return String from the handleRequest. I generate String from JSON using GSON.
Here's the method:
public String handleRequest(Map<String, String> input, Context context){
final Gson gson = new GsonBuilder().create();
String json;
//other logic here
json = gson.toJson(myPOJOResponseClass);
return json
}
I am getting this error: return type String is not compatible with myPOJOResponseClass
I tried to change the return type to Object didn't work. I tried to convert the String to JSON explicitly using JSONObject and changed the return type to JSONObject as well but that is not working either.
Any help would be appreciated.
PS: I am generating my POJO class using Lombok if that matters here.
You haven't provided much code for context, but based on the docs it looks like you have probably done something like this:
public class HelloPojo implements RequestHandler<Map<String, String>, myPOJOResponseClass>
Which would then mean that to implement the interface, your handleRequest(...) function needs to return myPOJOResponseClass.
If that is what is going on, try this:
public class HelloPojo implements RequestHandler<Map<String, String>, String>
I am trying to deserialize a JSON string into a Java object but I'm getting the following exception:
The JsonDeserializer com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter#306a30c7 failed to deserialized json object ["93"] given the type class java.util.ArrayList
My main file:
public static void main(String[] args) throws IOException {
String s = "{\"intents\":[\"93\"],\"_id\":\"frequestQueries\"}";
Gson gson = new Gson();
JavaObject a = gson.fromJson(s, JavaObject.class);
System.out.println(a);
The class which should represent the JSON is:
public class JavaObject {
public ArrayList intents;
private String _id ;
public JavaObject(){
intents = new ArrayList();
intents.add(93);
_id = "frequestQueries";
}
}
I tried the solutions given on SO with similar exceptions but I'm not able to figure out the exact reason. I tried this one but seems no concrete solution is given. My Gson version is 1.4.
Edit: I have updated my Gson to 2.8.0 and the exception went away.
I'm posting solution to my own question since many people using Arraylist in Gson deserialization like this one were suffering with the same problem. Just update Gson version and it will take care of Gson deserialization issue.
my use case included a similar class, using immutables (https://immutables.github.io/) :
#Value.Immutable
#Gson.TypeAdapters
public abstract class SampleClass {
public abstract String var1();
public abstract String var2();
public abstract Date date1();
}
I was converting it to Json string,using gson, and then getting the object again using :
SampleClass obj1 = new Gson().fromJson("generated_json_string",ImmutableSampleClass.class);
But now I had to change var1 to List of String, and now I am getting :
java.lang.RuntimeException: Failed to invoke com.google.common.collect.ImmutableList() with no args
What is the correct way to get the object from JSON string ?
Figured out what was wrong, hence answering the question.
Immutables generated class GsonAdaptersSampleClass, which implements TypeAdapterFactory. Using this and with the help of this answer : https://stackoverflow.com/a/13624060/3192744
I could find the following correct way to deserialize JSON string:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapterFactory(new GsonAdaptersSampleClass());
Gson gson = gsonBuilder.create();
SampleClass obj1 = gson.fromJson("generated_json_string",ImmutableSampleClass.class);
You can try GSON library for converting JSON to your existing class object.
http://howtodoinjava.com/best-practices/google-gson-tutorial-convert-java-object-to-from-json/
I am trying to deserialize a json object into a java bean.
The main issue I am facing is that I'd like to treat the field object of the json string as a plain string, even if it contains a potentially correct json object.
The json structure is like this:
{
"type":"user",
"object":{
"id":"1",
...}
}
How can i tell gson to ignore the object value so that it doesn't get deserialized into an object? I'd like it only to be mapped to a plain String field in my bean so that I can dispose a proper deserialization for it, once I got the type from the type field.
Just declare it as of type JsonObject
class ExampleJsonModel {
#SerializedName("type")
public String type;
#SerializedName("object")
public JsonObject object;
}
I don't know if your problem is solved. I ran into a similar question and here it is how I worked it out:
JsonDeserializer allows you to make you own adapter to deserialize that **:
class JavaBeanDeserializer implements JsonDeserializer<JavaBeanObject>() {
public JavaBeanObject fromJson(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
// return JavaBeanObject built using your logic.
}
You've to register JavaBeanDeserializer to Gson object when building it:
Gson gson = new GsonBuilder().registerTypeAdapter(JavaBeanObject.class, new JavaBeanDeserializer()).create();