Json to pojo convertions - java

How we convert following type of json into java object
{
"complaint_Map": {
"1000067730": "3011351597604397",
"1000067730-06": "10582576134561065"
}
}
if anyone have any idea about this tell how we do that.

With jackson
import com.fasterxml.jackson.databind.ObjectMapper;
Try
ObjectMapper mapper = new ObjectMapper();
String jsonInString = "{\"complaint_Map\":{\"1000067730\":\"3011351597604397\",\"1000067730-06\":\"10582576134561065\"}}";
Map<String,Object> pojo = mapper.readValue(jsonInString, Map.class);
System.out.println(((Map<String,Object>)pojo.get("complaint_Map")).get("1000067730")+"");
will print
3011351597604397

In java you can use Jackson library that converts a simple POJO to/from JSON.
From Wikipedia:
Jackson is a high-performance JSON processor for Java. Developers of it extol the combination of fast, correct, lightweight, and ergonomic attributes of the library.
Here an example taken by Wikipedia:
public class ReadWriteJackson {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
String jsonInput =
"{\"id\":0,\"firstName\":\"Robin\",\"lastName\":\"Wilson\"}";
Person q = mapper.readValue(jsonInput, Person.class);
System.out.println("Read and parsed Person from JSON: " + q);
Person p = new Person("Roger", "Rabbit");
System.out.print("Person object " + p + " as JSON = ");
mapper.writeValue(System.out, p);
}
}

You can do it with ObjectMapper from jackson.
Suppose the json is defines a java object,
then it can be done by
import org.codehaus.jackson.map.ObjectMapper;
YourObject mappingClassObject = new YourObject();
ObjectMapper mapper = new ObjectMapper();
try{
mappingClassObject = mapper.readValue(yourJSON, YourObject.class);
}catch(Exception e){
e.printStackTrace();
}

If you want a solution using Jackson library, here it is.
The custom class:
#JsonRootName("complaint_Map")
public class Complaint {
private String firstKey;
private String secondKey;
#JsonProperty("1000067730")
public String getFirstKey() {
return firstKey;
}
#JsonProperty("1000067730")
public void setFirstKey(String firstKey) {
this.firstKey = firstKey;
}
#JsonProperty("1000067730-06")
public String getSecondKey() {
return secondKey;
}
#JsonProperty("1000067730-06")
public void setSecondKey(String secondKey) {
this.secondKey = secondKey;
}
#Override
public String toString() {
return "Complaint{" +
"firstKey='" + firstKey + '\'' +
", secondKey='" + secondKey + '\'' +
'}';
}
}
And the way of testing:
String jsonString = "{\"complaint_Map\":{\"1000067730\":\"3011351597604397\",\"1000067730-06\":\"10582576134561065\"}}";
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
try {
Complaint complaint = mapper.readValue(jsonString, Complaint.class);
System.out.println(complaint);
} catch (Exception e) {
e.printStackTrace();
}
I used the following version (in Maven pom):
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.1.3</version>
</dependency>

Related

Jackson should not ignore root element tag in multi root xml content

I have the following xml content which I want to deserialize to JSON,
Input Content
<TransmissionAck>
<EchoedTransmissionHeader>
<TransmissionHeader>
<ReferenceTransmissionNo>26218</ReferenceTransmissionNo>
</TransmissionHeader>
</EchoedTransmissionHeader>
</TransmissionAck>
Expected output
{
"TransmissionAck": {
"EchoedTransmissionHeader":{
"TransmissionHeader":{
"ReferenceTransmissionNo":"26177"
}
}
}
}
Actual Output
{
"EchoedTransmissionHeader":{
"EchoedTransmissionHeader":{
"TransmissionHeader":{
"ReferenceTransmissionNo":"26177"
}
}}}
I am passing dynamic content from RestController(Spring Boot)
Mono<ResponseEntity<String>> otmXmlResponse = webRequestsService
.handlePost(Files.readString(Paths.get(outputFile.getAbsolutePath()), StandardCharsets.US_ASCII));
String body = otmXmlResponse.block().getBody();
String r = testXmlResponse(body);
============
public <T> T testXmlResponse(String xml) throws JsonMappingException, JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
XmlMapper xmlMapper = new XmlMapper();
xmlMapper.registerModule(new SimpleModule().addDeserializer(JsonNode.class,
new JsonNodeDeserializer() {
private static final long serialVersionUID = -5947022035338738709L;
public JsonNode deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException {
XMLStreamReader xmlP = ((FromXmlParser) p).getStaxReader();
String rootName = xmlP.getLocalName().toString();
return ctxt.getNodeFactory().objectNode().set(rootName, super.deserialize(p, ctxt));
}
}));
JsonNode entries = xmlMapper.readTree(inputFile);
String json = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(entries);
return (T) json;
}
When I run a unit test I get expected output, but when I call the deserialize method as above with dynamic content from controller, the sub-root element is taken as root. I cannot use a POJO for mapping. Any idea how I can get the expected output using Jackson library? Thanks.
Try this, I used
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20140107</version>
</dependency>
import org.json.*;
public class ConvertXML {
public static String xml = "<TransmissionAck>\r\n" + " <EchoedTransmissionHeader>\r\n"
+ " <TransmissionHeader>\r\n"
+ " <ReferenceTransmissionNo>26218</ReferenceTransmissionNo>\r\n"
+ " </TransmissionHeader>\r\n" + " </EchoedTransmissionHeader>\r\n" + "</TransmissionAck>";
public static void main(String[] args) {
try {
JSONObject json = XML.toJSONObject(xml);
String jsonString = json.toString(4);
System.out.println(jsonString);
} catch (JSONException e) {
System.out.println(e.toString());
}
}
}

Java: Get value from a Json string (Set<String>)

I'm using this method that returns a Set<String> but in fact what I got is a Json string like this
[
{
"id":"Id1"
},
{
"id":"Id2",
"title":"anyTitle"
}
]
My goal is to get the value of key "id". I've also made a java bean to map the data:
public class Data {
private String id;
private String title;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
I tryied to parse using gson but all I can get is an error: Cannot cast 'java.util.LinkedHashMap$LinkedKeyIterator' to 'com.google.gson.stream.JsonReader'
So, obviously I'm doing something wrong:
Set<String> availableData = getData(); //this method returns a json string
Iterator<String> itr = availableData.iterator();
while (itr.hasNext()) {
Gson gson = new Gson();
JsonParser parser = new JsonParser();
JsonObject object = (JsonObject) parser.parse(itr.next());
Data data = gson.fromJson(object, Data.class);
}
update: The actual error is: Type mismatch Can't assign com.google.common.collect.Maps$TransformedEntriesMap to java.lang.String
In that line you pass an iterator:
JsonObject object = (JsonObject) parser.parse((JsonReader) itr);
But you should pass a next element:
JsonObject object = (JsonObject) parser.parse(itr.next());
In addition you got an extra comma in you JSON.
You can replace the whole block with that line:
Data data = gson.fromJson(itr.next(),Data.class)
Use Jackson mapper. You can directly convert it into an object and retrieve through getters.
ObjectMapper objectMapper = new ObjectMapper();
String carJson =
"{ \"brand\" : \"Mercedes\", \"doors\" : 5 }";
try {
Car car = objectMapper.readValue(carJson, Car.class);
System.out.println("car brand = " + car.getBrand());
System.out.println("car doors = " + car.getDoors());
} catch (IOException e) {
e.printStackTrace();
}
So, following this related issue: https://github.com/seleniumhq/selenium-google-code-issue-archive/issues/5154, finally I map this using JSONArray and streams from java8
Set<String> availableData = getData();
JSONArray dataArray = new JSONArray(availableData);
List<Object> dataList = dataArray.toList();
Object o = dataList.stream()
.filter(c -> ((Map) c).get("id").toString().contains("Id1"))
.findFirst().orElse(null);
return ((Map)o).get("id").toString();
Maybe you want to known how to use Gson to unserialized json to java object.
Here are two ways I can give you.
public void parse() {
String jsonString = "[\n" +
" {\n" +
" \"id\":\"Id1\"\n" +
" },\n" +
" {\n" +
" \"id\":\"Id2\",\n" +
" \"title\":\"anyTitle\"\n" +
" }\n" +
"]";
Gson gson = new Gson();
// Use Gson Type
Type setType = new TypeToken<HashSet<Data>>(){}.getType();
Set<Data> dataSet = gson.fromJson(jsonString, setType);
// Print [Data{id='Id2', title='anyTitle'}, Data{id='Id1', title='null'}]
System.out.println(dataSet);
// Use Java Array
Data[] dataArray = gson.fromJson(jsonString, Data[].class);
// Print [Data{id='Id1', title='null'}, Data{id='Id2', title='anyTitle'}]
System.out.println(Arrays.toString(dataArray));
}

Extracting the value of an element from a JSON

I'm trying to make a test where I get some documents based on the id of the batch they belong to. More specifically, I want to check that a specific batchPublicId is in the response body. I am using okhttp for the test.
This a shorter version of the json:
{
"_embedded": {
"invoices": [
{
"type": "INVOICE",
"publicId": "27bc8426-17cf-4fe5-9278-64108ae05e4b",
"deliveryStatus": null,
"processingStatus": "INITIATED",
"batchPublicId": "0000000000000000000000001"
}
]
}
}
I'm new to json and this is how far I got with the problem:
String invoicesJsonData = response.body().string();
JSONObject invoicesJsonObject = new JSONObject(invoicesJsonData);
Assert.assertTrue(invoicesJsonObject.getJSONObject("_embedded") !=null && invoicesJsonObject.getJSONObject("_embedded").has("invoices"));
I would like to verify that batchPublicId has the value mentioned in the json. Is there a way to do this? Thank you.
String invoicesJsonData = response.body().string();
JSONObject invoicesJsonObject = new JSONObject(invoicesJsonData);
JSONObject invoicesJsonObject1 = invoicesJsonObject.getJSONObject("_embedded");
JSONArray f2=invoicesJsonObject1.getJSONArray("invoices");
for(int i=0;i<f2.length();i++){
JSONObject obj=f2.getJSONObject(i);
if(obj.get("batchPublicId")!=null){
System.out.println(obj.get("batchPublicId"));
}
You can do something like this,Which worked out for me sometimes back.
String invoicesJsonData = response.body().string();
JSONObject invoicesJsonObject = new JSONObject(invoicesJsonData);
JSONObject invoicesJsonObject = json.getJSONObject("invoicesJsonObject");
String batchPublicId = invoicesJsonObject.getString("batchPublicId");
System.out.println( "batchPublicId: " + batchPublicId );
if(batchPublicId !=null){
// do something
}
Not sure about the syntax.Giving you a hint.
you can check any keys is there in json object or not like below :
if(jsonObject1.has("batchPublicId")){
String batchPublicId = jsonObject1.optString("batchPublicId");
Log.i(getClass().getSimpleName(), "batchPublicId=" + batchPublicId);}
has method is used to find any key is there in jsonobject or not.
In my opinion, a better approach for this would be to create a POJO from this JSON string, and extract the information you need using simply the getters
For example:
Wrapper class:
#JsonIgnoreProperties(ignoreUnknown = true)
#JsonRootName(value = "_embedded")
public class Embeded {
#JsonProperty("invoices")
private List<Invoice> invoices;
public Embeded() {}
public List<Invoice> getInvoices() {
return invoices;
}
public void setInvoices(List<Invoice> invoices) {
this.invoices = invoices;
}
}
Invoice class:
#JsonIgnoreProperties(ignoreUnknown = true)
public class Invoice {
#JsonProperty("type")
private String type;
#JsonProperty("publicId")
private String publicId;
#JsonProperty("deliveryStatus")
private String deliveryStatus;
#JsonProperty("processingStatus")
private String processingStatus;
#JsonProperty("batchPublicId")
private String batchPublicId;
public Invoice() {}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getPublicId() {
return publicId;
}
public void setPublicId(String publicId) {
this.publicId = publicId;
}
public String getDeliveryStatus() {
return deliveryStatus;
}
public void setDeliveryStatus(String deliveryStatus) {
this.deliveryStatus = deliveryStatus;
}
public String getProcessingStatus() {
return processingStatus;
}
public void setProcessingStatus(String processingStatus) {
this.processingStatus = processingStatus;
}
public String getBatchPublicId() {
return batchPublicId;
}
public void setBatchPublicId(String batchPublicId) {
this.batchPublicId = batchPublicId;
}
}
Test:
public void json_test() throws JsonParseException, JsonMappingException, IOException {
String json = "{"
+ "\"_embedded\": {"
+ "\"invoices\": ["
+ "{"
+ "\"type\": \"INVOICE\","
+ "\"publicId\": \"27bc8426-17cf-4fe5-9278-64108ae05e4b\","
+ "\"deliveryStatus\": null,"
+ "\"processingStatus\": \"INITIATED\","
+ "\"batchPublicId\": \"0000000000000000000000001\""
+ "}"
+ "]"
+ "}"
+ "}";
ObjectMapper mapper = new ObjectMapper();
mapper.configure(Feature.UNWRAP_ROOT_VALUE, true);
List<Invoice> invoices = mapper.readValue(json, Embeded.class).getInvoices();
Assert.assertTrue(StringUtils.equals(invoices.get(0).getBatchPublicId(), "0000000000000000000000001"));
}
If I understand your right, you just need to call:
Assert.assertTrue(invoicesJsonObject.getString("batchPublicId").equals("0000000000000000000000001"));"
If you want to create a test for JSON Validation, you can use the JSONAssert.
JSONAsset give the method assertEquals, that compare two json structures, strict identic or not.
final String expected_result = YOUR_EXPECTED_RESULT;
JSONAssert.assertEquals(YOUR_EXPECTED_JSON_RESULT, RESULT_FROM_RESPONSE_BODY, false);
The last boolean parameter defines if you want an strict comparation or just compare if your expected result is in result from response.

GSON: Convert JSON To Object with ignorance

I had JSON model for success some this
{
data: {
.....
}
}
so I've create model:
Class Model{
public Data data;
}
and I've used
new Gson().fromJson(Model.class) to convert in Object. It works fine. Now my problem starts with when I get error in same API and its json Get changed
{
message: {
.....
}
}
I want to use same model to be serialized in Json.
Class Model{
public Data data;
public Massage message;
}
But it gives me following Exception: Expected a string but was BEGIN_OBJECT at line 1 column 13
Just configure and use ObjectMapper from Jackson lib:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.3</version>
</dependency>
The mapper should be defined as
ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Please see full Demo example
public class Demo {
public static void main(String[] args) throws IOException {
String jsonData = "{" +
" \"data\": {" +
" }" +
"}";
String jsonMessage = "{" +
" \"message\": {" +
" }" +
"}";
ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Model modelData = mapper.readValue(jsonData, Model.class);
Model modelMessage = mapper.readValue(jsonMessage, Model.class);
System.out.println(modelData);
System.out.println(modelMessage);
}
}
class Model {
private Data data;
private Message message;
#Override
public String toString() {
return "Model{" +
"data=" + data +
", message=" + message +
'}';
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public Message getMessage() {
return message;
}
public void setMessage(Message message) {
this.message = message;
}
private static class Data {}
private static class Message {}
}
BTW, ObjectMapper is Thread Safe, so you can define one constant to not create it each time when you read Json.
More info you can find here: http://fasterxml.github.io/jackson-databind/javadoc/2.8/com/fasterxml/jackson/databind/ObjectMapper.html

How to deserialize a JSON with integer as key?

I have a JSON which looks like this:
{
"MeterRates": {
"0": 0.142,
"1024": 0.142,
"51200": 0.142,
"512000": 0.142,
"1024000": 0.1278,
"5120000": 0.1051
}
}
This JSON is actually a part of a larger JSON file, I extracted only the part I was having difficulty deserializing. I need to deserialize this into a Java object. I tried doing this using the following class, but it gives me null values for all keys.
public class MeterRates {
private Double rate0;
private Double rate1024;
private Double rate51200;
private Double rate512000;
private Double rate1024000;
private Double rate5120000;
#JsonProperty("0")
public Double getRate0() {
return rate0;
}
public void setRate0(Double rate0) {
this.rate0 = rate0;
}
#JsonProperty("1024")
public Double getRate1024() {
return rate1024;
}
public void setRate1024(Double rate1024) {
this.rate1024 = rate1024;
}
#JsonProperty("51200")
public Double getRate51200() {
return rate51200;
}
public void setRate51200(Double rate51200) {
this.rate51200 = rate51200;
}
#JsonProperty("512000")
public Double getRate512000() {
return rate512000;
}
public void setRate512000(Double rate512000) {
this.rate512000 = rate512000;
}
#JsonProperty("1024000")
public Double getRate1024000() {
return rate1024000;
}
public void setRate1024000(Double rate1024000) {
this.rate1024000 = rate1024000;
}
#JsonProperty("5120000")
public Double getRate5120000() {
return rate5120000;
}
public void setRate5120000(Double rate5120000) {
this.rate5120000 = rate5120000;
}
#Override
public String toString() {
return "MeterRates [0 = " + rate0 + " 1024 = " + rate1024 + " 51200 = " + rate51200 + " 512000 = " + rate512000 + " 1024000 = " + rate1024000
+ " 5120000 = " + rate5120000 + "]";
}
}
I tried referring to this question which has similar requirements but couldn't quite get how to do it.
UPDATE 1:
The code I am using to deserialize is as follows, wherein I am passing the class as MeterRates.class:
public static <T> T unmarshalJSON(HttpEntity entity, Class<T> clazz) {
InputStream is = null;
try {
return new Gson().fromJson(EntityUtils.toString(entity), clazz);
} catch (ParseException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
if (null != is) {
is.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
You're trying to influence how Gson (a JSON mapper) deserializes an object by annotating its class with Jackson annotations (another, different JSON mapper).
That can't possibly work. Gson doesn't care about Jackson annotations.
If you want these annotations to be taken into account, use Jackson to deserialize your JSON. Here is a complete example serializing and deserializing an object using Jackson (I changed the type of the fields to Double, as that's what they should be):
MeterRates rates = new MeterRates();
rates.setRate1024(0.7654);
rates.setRate51200(0.4567);
ObjectMapper objectMapper = new ObjectMapper();
String s = objectMapper.writeValueAsString(rates);
System.out.println("s = " + s);
MeterRates m = objectMapper.readValue(s, MeterRates.class);
System.out.println("m = " + m);
You can make use of Jackson JSON API.
http://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson/

Categories