How to map json response to pojo - java

What should I do to convert json response to object(pojo) using GSON lib? I have response from webservice:
{"responce":{"Result":"error","Message":"description"}}
and create POJO
public class ErrorResponse {
private String result;
private String message;
}
but
ErrorResponse errorResponse = (ErrorResponse) gson.fromJson(new String(responseBody), ErrorResponse.class);
gets an error
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 14
UPD
OK, i created
public class Wrapper {
#SerializedName("Responce")
private ErrorResponse response;
// get set
}
public class ErrorResponse {
#SerializedName("Result")
private String result;
#SerializedName("Message")
private String message;
// get set
Wrapper wrapper = (Wrapper) gson.fromJson(new String(responseBody), Wrapper.class);
ErrorResponse errorResponse = wrapper.getResponse();
and finally I get NPE errorResponse

Your JSON is actually a JSON object containing a JSON object named response. That JSON object has the format of your Pojo.
So one option is to create that hierarchy in Java
public class Wrapper {
private ErrorResponse response;
// getters & setters
}
And deserialize that
Wrapper wrapper = (Wrapper) gson.fromJson(new String(responseBody), Wrapper.class);
ErrorResponse errorResponse = wrapper.getResponse();
An alternative is to parse the JSON into a JsonElement which you use to get the JSON object named response and convert that one. Use the following types from the Gson library:
import com.google.gson.JsonParser;
import com.google.gson.GsonBuilder;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
//...
Gson gson = new GsonBuilder().create();
JsonParser parser = new JsonParser();
JsonElement jsonElement = parser.parse(json);
ErrorResponse response = gson.fromJson(jsonElement.getAsJsonObject().get("response"), ErrorResponse.class);
Note that your class' field names must match the JSON or vice versa. result vs Result. Or you can use #SerializedName to make it match
#SerializedName("Response")
private String response;

You can use jsonschema2pojo online POJO generator to generate a POJO class from a JSON document or JSON schema with the help of GSON library. In the 'Annotation style' section, choose GSON. Once the zip file is created, extract it and add all the classes to your classpath.
Note: you will need to add GSON jars to your project.

Related

How to deserialize a Json Object having hyphen or dash i.e - in its attribute name .. using GSON

Sample Json -
{"error":
{"message":"irp-return-error",
"irp-err":{"ErrorCode":"1015","ErrorMessage":"Invalid Data for this user"}
}
}
I tried setting the name using #SerializedName Gson annotation
public class Error {
#SerializedName("irp-err")
private IrpErr irpErr;
private String message;
but the call to the json object returns null.
Gson erngson = new Gson();
ErrResponse data = erngson.fromJson(response.readEntity(String.class), ErrResponse.class);
if(data.getError()!=null){
IrpErr irperr = data.getError().getIrpErr(); //NPE
}

Convert multiple Java Beans to JSON

I have multiple Java bean classes that are associated to each other (JSON Array + JSON Object) since they have a nested structure.
There are about 10 classes. Is there a way to collectively convert these classes or at-least one by one?
I had created these classes out of a JSON data which I don't have access to right now.
So, now, what I'm looking forward is to create a dummy JSON out of those classes.
Using GSON, I tried converting one of these Bean classes however, I got an empty result. Here is one of the beans called Attachment.java.
Attachment.java
package mypackagename;
import java.io.Serializable;
public class Attachment implements Serializable{
private Payload payload;
private String type;
public Payload getPayload() {
return payload;
}
public void setPayload(Payload payload) {
this.payload = payload;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
Implementation
Gson gson = new Gson();
Attachment attachment = new Attachment();
String json = gson.toJson(attachment);
Sure you got an empty result. Because your JSON object is empty. You should add data to your object and test it again as below:
Attachment attachment = new Attachment(new Payload("Test Payload"), "Test attachment");
String json = new Gson().toJson(attachment);
Log.e("Test", "Json: " + json); // result: Json: {"payload":{"test":"Test Payload"},"type":"Test attachment"}
To avoid empty object, you have to set a default value to your payload and type becaus Gson will ignore any null value.
This section of the Gson User Guide: https://sites.google.com/site/gson/gson-user-guide#TOC-Finer-Points-with-Objects
The fourth bullet point explains how null fields are handled.

How to handle a response of a service returning either a single object or an array of these?

I am trying to invoke a third-party API through REST call in Spring. Currently, I'm using postForObject. I am converting the request class to string and calling the post for object. The response is taken as string and then converted it into the class. I have defined the class with below parameters
Class responseDto {
private Arraylist < Response > response;
getResponse();
setResponse();
}
Response {
String code;
String trid;
Getters();
Setters();
}
I am using Jackson dependency to serialize and deserialize. This class is working fine for the below response:
{
"response":[
{
"code":"100",
"trid":"123"
}
]
}
However, in error scenario, the request returns a JSON class with the same name 'response' as given below
{
"response":{
"code":"700",
"trid":"123"
}
}
The deserialize fails for the class I defined with some JSON mapping exception:
com.fasterxml.jackson.databind.JsonMappingException: Can not
deserialize instance of java.util.ArrayList out of START_OBJECT token
How can I resolve this issue in Java and Spring?
SOLUTION 1: Using #JsonFormat ( > 2.6 version)
Just annotate your field with #JsonFormat as
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonFormat.Feature;
public class ResponseDto {
#JsonFormat(with = Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
private List<Response> response;
public List<Response> getResponse() {
return response;
}
public void setResponse(List<Response> response) {
this.response = response;
}
}
SOLUTION 2: Setting DeserializationFeature
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
// global setting, can be overridden using #JsonFormat in beans
// when using #JsonFormat on fields, then this is not needed
mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
ResponseDto dto = mapper.readValue(stringResponse, ResponseDto.class);
}
Now response node in json containing single object, single object array, multiple object array will be successfully parsed as list of Response object.

want to map a json object unto a java object

I am using a certain API which have a json output as below. I have parsed it to String.
the json output as string: {"result":{"number":"INC0022500"}}.
As you can see it has nested object for key result.
my snippet which i am using to map the above json unto a object.
Gson gson = new Gson();
EspIncidentTrial staff = gson.fromJson(json, EspIncidentTrial.class);
ESPIncidentTrial class:
import javax.persistence.Embeddable;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;
#Embeddable
#JsonIgnoreProperties(ignoreUnknown = true)
public class EspIncidentTrial {
#JsonProperty("result")
private ResultTrial result;
public ResultTrial getResult() {
return result;
}
public void setResult(ResultTrial result) {
this.result = result;
}
}
For the nested object i created another class ResultTrial. Below is the body.
ResultTrial class:
import javax.persistence.Embeddable;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;
#Embeddable
#JsonIgnoreProperties(ignoreUnknown = true)
public class ResultTrial {
#JsonProperty("number")
private String incidentId;
public String getIncidentId() {
return incidentId;
}
public void setIncidentId(String incidentId) {
this.incidentId = incidentId;
}
}
What happens now is, in EspIncidentTrial class, object result is getting mapped. However, inside ResultTrial class, no mapping is being done.
I tried treating the key result in the json object as String, but the threw the below error, which was expected though.
The error occured while parsing the JSON. com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 12 path $.result
Please help!
Here you are mixing gson and Jackson.
You are using annoations of Jackson, but using GSON's method to deserailze it.
Use Jackson's objectMapper to deserialize.
E.g.:
ObjectMapper mapper = new ObjectMapper();
EspIncidentTrial staff = mapper.readValue(json, EspIncidentTrial.class);
you can try this....
String searchdata="{\"userPojo\":{\"userid\":1156}}";
JSONObject jsonObject=new JSONObject(searchdata);
SummaryPojo summaryPojo=new SummaryPojo();
if(searchdata.contains("userPojo"))
{
String jsonstring=jsonObject.getString("userPojo");
Gson gson = new Gson();
UserPojo userPojo = gson.fromJson(searchdata, UserPojo.class);
summaryPojo.setUserPojo(userPojo);
}

What can be a sample JSON payload for my object structure?

I'm new to JSON hence the answer to my question would be a huge help!
I have an enum like below:
enum Error
{
private final String message;
INVALID("failed"),
VALID("succeeded");
Error(String message){
this.message = message;
}
}
And my class is like:
class Response {
String id;
Error error;
}
How do I create a sample JSON payload for this?
If you instantiate and serialize you class using Gson, you will get a JSON string that is the exactly payload you are looking for.
For example, if you execute this:
Response r = new Response();
r.id="AA";
r.error = Error.INVALID;
Gson defaultGson = new Gson();
System.out.println(defaultGson.toJson(r));
you will get
{"id":"AA","error":"INVALID"}
Of course, you could use alternative way to serialize/deserialize your enum like asked here

Categories

Resources