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);
}
Related
I need to receive some message with SOAP so I've generated a few classes by xsd-scheme and maven-jaxb2-plugin like this:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "Claim", propOrder = {
"field",
})
public class ClaimType {
#XmlElement(required = true, type = Integer.class, nillable = false)
protected Integer field;
public Integer getField() {
return bpType;
}
public void setField(Integer value) {
this.field= value;
}
}
After receiving message I need to send these to the next one microservice in wrap of HashMap.
I supposed to use ObjectMapper to convert:
//JAXB DTO --> JSON
ObjectMapper objectMapper = new ObjectMapper();
String jsonContent = objectMapper.writeValueAsString(claimType);
map.put("json", jsonContent);
//JSON --> JAXB DTO
ObjectMapper objectMapper = new ObjectMapper();
String json = map.get("json");
ClaimType claimType = objectMapper.readValue(json, ClaimType.class);
But the generated classes are haven't any constructors so I got the exception like "
No creator like default constructor are exists".
What is the best preactice to work with Jaxb Dto? Can I do smth to successful convert these json to object? Thanks in advance!
I've solved my problem by using ObjectMapper MixIn:
import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;
#JsonIgnoreProperties(value = {"globalScope", "typeSubstituted", "nil"})
public abstract class JAXBElementMixIn<T> {
#JsonCreator
public JAXBElementMixIn(#JsonProperty("name") QName name,
#JsonProperty("declaredType") Class<T> declaredType,
#JsonProperty("scope") Class scope,
#JsonProperty("value") T value) {
}
}
And the convertation:
import com.fasterxml.jackson.databind.ObjectMapper;
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.addMixIn(JAXBElement.class, JAXBElementMixIn.class);
solution link
At a certain point in my code, I have parse a JSON document, represented as a string, to a JsonNode, because I don't know yet the actual target pojo class type.
Now, some time later, I know the Class instance of the pojo and I want to convert this JsonNode to an actual pojo of that class (which is annotated with the proper #JsonProperty annotations). Can this be done? If so, how?
I am working with Jackson 2.10.x.
In this case you can use two methods:
treeToValue
convertValue
See below example:
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.util.StringJoiner;
public class JsonNodeConvertApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(jsonFile);
System.out.println(mapper.treeToValue(node, Message.class));
System.out.println(mapper.convertValue(node, Message.class));
}
}
class Message {
private int id;
private String body;
// getters, setters, toString
}
Above code for JSON payload like below:
{
"id": 1,
"body": "message body"
}
prints:
Message[id=1, body='message body']
Message[id=1, body='message body']
I have the following code which should parse a simple json as follows:
{"jsonTest":
{"innerKey":"innerValue"}
}
Here, the value of 'jsonTest' is a json object.
Question : Can this JSON be parsed (using jackson) and retrieve the value of 'jsonTest' as a simple String? In other words, is there a way to ask the parser not to parse the inner json object?
here is what I tried so far. This results in a parsing exception
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonParserTest {
public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
ObjectMapper mapper = new ObjectMapper();
String json = "{\"jsonTest\":{\"innerKey\":\"innerValue\"}}";
TestJson js = mapper.readValue(json, TestJson.class);
System.out.println(js.getJsonTest());
}
}
class TestJson {
private String jsonTest;
public String getJsonTest() {
return jsonTest;
}
public void setJsonTest(String jsonTest) {
this.jsonTest = jsonTest;
}
}
You can use JsonNode for this. Just change your TestJson class:
class TestJson {
private JsonNode jsonTest;
public JsonNode getJsonTest() {
return jsonTest;
}
public void setJsonTest(JsonNode jsonTest) {
this.jsonTest = jsonTest;
}
}
Output:
{"innerKey":"innerValue"}
Also you can do it just using the JsonNode without the TestJson class.
Use the following mapper.readTree method:
JsonNode jsonNode = mapper.readTree(json);
System.out.println(jsonNode.get("jsonTest").toString());
You should create structure to deseralize that json. It could be something like this:
#Data
#NoArgsConstructor
class TestJson {
JsonTest jsonTest;
#Data
#NoArgsConstructor
private static class JsonTest {
String innerKey;
}
}
I am not able to unmarshall a JSON key which can hold either a string value or an another JSON Object using Jackson Library.
Ex:- Below are the two possible values.
1)
"ProviderData": {
"INVALID": "HEX",
"#text": "Sample"
}
2)
"ProviderData": "1C"
Could someone please verify and suggest me on this issue.
You can write custom deserialiser and handle these both cases or write two constructors for ProviderData POJO class and properly use JsonCreator and JsonCreator annotations. See below example:
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
public class JsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.readValue(jsonFile, Response.class));
}
}
class Response {
#JsonProperty("ProviderData")
private ProviderData data;
// getters, setters, toString
}
class ProviderData {
private static final String INVALID_NAME = "INVALID";
private static final String TEXT_NAME = "#text";
#JsonProperty(INVALID_NAME)
private final String invalid;
#JsonProperty(TEXT_NAME)
private final String text;
#JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public ProviderData(String invalid) {
this(invalid, null);
}
#JsonCreator
public ProviderData(#JsonProperty(INVALID_NAME) String invalid, #JsonProperty(TEXT_NAME) String text) {
this.invalid = invalid;
this.text = text;
}
// getters, toString
}
For this JSON payload:
{
"ProviderData": {
"INVALID": "HEX",
"#text": "Sample"
}
}
Above example prints:
Response{data=ProviderData{invalid='HEX', text='Sample'}}
And for String primitive JSON payload:
{
"ProviderData": "1C"
}
Above example prints:
Response{data=ProviderData{invalid='1C', text='null'}}
As you can see, JSON Object is mapped properly using 2-arg constructor and String primitive is mapped using 1-arg constructor and we assume that this value means invalid key from JSON Object example.
See also:
Custom JSON Deserialization with Jackson.
sequentially deserialize using Jackson.
Deserialize strings and objects using jackson annotations in java.
you could deserialize to JsonNode and then extract the contents individually, or deserialize to an Object and use instanceof to determine if it's a Map or another type, or use a custom deserializer to unpack the data into a custom object that handles both cases.
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.