How to get java objects from JSONArray url using Jackson in Android - java

This is my JSON from URL
https://api.myjson.com/bins/142jr
[
{
"serviceNo":"SR0000000001",
"serDate":"17",
"serMonth":"DEC",
"serYear":"2015",
"serTime":"02.30 AM",
"serApartmentName":"Galaxy Apartments"
},
{
"serviceNo":"SR0000000002",
"serDate":"19",
"serMonth":"JUN",
"serYear":"2016",
"serTime":"03.30 AM",
"serApartmentName":"The Great Apartments"
}
]
I have one ListView I want populate details from online JSON,above i given a link and sample json anybody given sample jackson code in java
Thanks for advance,
Rajesh Rajendiran

To use jackson you need to create a model class:
[
{
"serviceNo":"SR0000000001",
"serDate":"17",
"serMonth":"DEC",
"serYear":"2015",
"serTime":"02.30 AM",
"serApartmentName":"Galaxy Apartments"
},
{
"serviceNo":"SR0000000002",
"serDate":"19",
"serMonth":"JUN",
"serYear":"2016",
"serTime":"03.30 AM",
"serApartmentName":"The Great Apartments"
}
]
For the above the json the model class would be:
public class SomeClass {
private String serviceNo;
private String serDate;
private String serMonth;
private String serYear;
private String serTime;
private String serApartmentName;
#JsonProperty("serviceNo") //to bind it to serviceNo attribute of the json string
public String getServiceNo() {
return serviceNo;
}
public void setServiceNo(String sNo) { //#JsonProperty need not be specified again
serviceNo = sNo;
}
//create getter setters like above for all the properties.
//if you want to avoid a key-value from getting parsed use #JsonIgnore annotation
}
Now whenever you have the above json as string stored in a variable say jsonString use the following code to parse it:
ObjectMapper mapper = new ObjectMapper(); // create once, reuse
ArrayList<SomeClass> results = mapper.readValue(jsonString,
new TypeReference<ArrayList<ResultValue>>() { } );
results should now contain two SomeClass objects having the above json parsed as respective objects.
PS: Its been a long time since I have used Jackson for parsing so this code might need some improvements.

If you are getting this as http response then I would suggest to use spring rest template for android.
It has support for Message Converters. That way the onus of marshaling and unmarshalling.
[Update]
Here is a blog for the same :http://www.journaldev.com/2552/spring-restful-web-service-example-with-json-jackson-and-client-program
Refer Docs for more details:
http://docs.spring.io/spring-android/docs/current/reference/html/rest-template.html

Related

How can I introduce escape characters to my JSON mapper?

I am trying to make a simple thing using com.fasterxml.jackson.databind.ObjectMapper.
I have an object I want to translate to String.
class Car{
String color;
String brand;
//... more class info
}
It is working fine and I get my String as it should but the result looks like this:
{"color: "blue", "brand": "toyota" }
Is it possible to make it look like:
{\"color\": \"blue\", \"brand\", \"toyota\" }
I'm not sure if this breaks the JSON expected format.
I've read the docs and seems like I can use this:
ObjectMapper().factory.setCharacterEscapes(...)
But I'm not sure how to pass it or from which repo. Any ideas?
Use Jackson to generate valid JSON payload and StringEscapeUtils to escape it.
Example code:
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.text.StringEscapeUtils;
public class EscapeJsonApp {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(new Car("blue", "Toyota"));
String escapedJson = StringEscapeUtils.escapeJson(json);
System.out.println(escapedJson);
}
}
class Car {
String color;
String brand;
// getters, setters, constructor
}
Above code prints:
{\"color\":\"blue\",\"brand\":\"Toyota\"}
Maven dependency:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.8</version>
</dependency>
I am basically trying to make a mapper for an sort of inner object to
match a SNS format https://docs.aws.amazon.com/sns/latest/dg/sns-send-custom-platform-specific-payloads-mobile-devices.html
Here's one of the examples from that page:
{
"GCM":"{\"data\":{\"message\":\"Check out these awesome deals!\",\"url\":\"www.amazon.com\"}}"
}
That's a JSON object with a single field named "GCM" whose value is a string. The content of the string is another JSON object.
Let's take your Car class as an example, and assume you want to generate this JSON as your output:
{
"car": "{\"color\": \"blue\", \"brand\": \"toyota\"}"
}
First you'll need to convert your Car object to a JSON string. Then you create another JSON object and stuff the car's JSON string into a field of this outer object:
String carJson = objectMapper.writeValueAsString(myCar);
Map<String, Object> outerObject = singletonMap("car", carJson);
String finalResult = objectMapper.writeValueAsString(outerObject);
I think that you can use something like JSONObject.quote(json):
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(new Car("blue", "Toyota"));
System.out.println(JSONObject.quote(json));
Output:
"{\"color\": \"blue\", \"brand\", \"toyota\" }"

How to map multiple JSON responses to a single Java POJO?

Need to map multiple types of JSON responses to a single POJO so that I can compare the different objects to provide insight about the differences.
I had tried mapping the first response to the POJO and parsed the second response to populate the defined POJO:
class XXX {
#JsonProperty("accountHolder")
private String accountHolder;
#JsonProperty("routingNumber")
private String routingNumber;
#JsonProperty("balance")
private List<Balance> balance;
#JsonProperty("accountName")
private String accountName;
#JsonProperty("bankTransferCodeType")
private String bankTransferCodeType;
#JsonProperty("individualInformation")
private IndividualInformation individualInformation;
#JsonProperty("acctType")
private String acctType;
#JsonProperty("transactionList")
private TransactionList transactionList;
#JsonProperty("accountNumber")
private String accountNumber;
#JsonProperty("uniqueId")
private String uniqueId;
#JsonProperty("bankNetID")
private String bankNetID;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
}
First response:
[
{
"ACCOUNT_NAME": "",
"ACCOUNT_NUMBER": "",
"AVAILABLE_BALANCE": null,
"CURRENT_BALANCE": "",
"FULL_ACCOUNT_NUMBER": null,
}
]
Second response:
"bankAccount": [
{
"accountName": "",
"accountNumber": "",
"routingNumber": "",
"fullAccountNumber": "",
"bankTransferCodeType": "",
"acctType": "",
"transactionList": {
"transaction": [
{
"amount": {
"curCode": "",
"content": ""
}
],
"oldestTxnDate": ""
},
"uniqueId":
}
}
Expecting a generic way to map the different structured JSON entities to single POJO.
How to map multiple JSON responses to a single Java POJO?
As both responses seem to be completely different from each other, with nothing in common, I would refrain from attempting to use a single class for reading both responses.
Expecting a generic way to map the different structured JSONs to single POJO.
You could parse both responses as a Map<String, Object> and then map the values to a common class.
You could create separated classes for mapping each response. It will allow you to decouple them and evolve them as you need. You also can use use mapping frameworks such as MapStruct for reducing the boilerplate code when mapping from one object to another.
It doesn’t seems to have any generic way. But you can do this:
Create multiple domain classes for each response type
Create a single standard domain class
Create mapper for each response class to map that to standard domain
class. You can use MapStruct reference here
I would suggest using Jackson Json Views. Here is an example for the same :
Example
public class Views {
public class Global {
}
public class Internal extends Global {
}
}
class XXX {
#JsonView(Views.Global.class)
#JsonProperty("accountHolder")
private String accountHolder;
#JsonView(Views.Internal.class)
#JsonProperty("routingNumber")
private String routingNumber;
}
Hope it helps.
What I did is I created a MyResponse model containing basically all response fields from the JSON response you expect to get.
MyResponse has c-tor or receiving these fields or setters allowing setting them.
Then I created some kind of service class MyService that can issue multiple requests and gets responses back.
Then you just do something like this in some kind of manager class or whatever you call it:
MyService mySer = new MyService();
MyResponse myRes = new MyResponse(
mySer.getDetails(),
mySer.getPicture(),
mySer.getSomethingElse()
);
These calls (getDetails, getPicture...) send requests to end point and return responses which are then just mapped into the the fields of MyResponse class constructor. This happens by the framework so MyResponse has annotations #XmlRootElement and #XmlAccessorType of type FIELD to ensure that happens.
If for whatever reason, you dont want to create response containing result of getPicture for example, you just assign null to that imput parameter.
I suggest to use #JsonProperty("") and #JsonAlias("").
class XXX {
#JsonAlias("accountName")
#JsonProperty("ACCOUNT_NAME")
private String name;
#JsonAlias("routingNumber")
#JsonProperty("ROUTING_NUMBER")
private String routing;}
I hope it helps.

How to add objects to JSON

In post service, I am using below method to parse and update Database:
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(<String>);
UserLogin userLogin = mapper.convertValue(node.get("UserLogin"), UserLogin.class);
UserSecurityDetails userSecurityDetails = mapper.convertValue(node.get("UserSecurityDetails"), UserSecurity
Now, In get service, I want to send the same data by retieving from DB and adding to JSON. Could anyone suggest what is the best way?
Sample JSON to be formed:
{
"UserLogin":
{
"user_login_id": "10011",
"user_password": "password"
},
"UserSecurityDetails":
{
"user_sequence_id": "1",
"seq_question_id": "1",
"seq_answer": "Test Answer"
}
}
Create a Wrapper POJO having UserLogin and UserSecurityDetails. Jackson will automatically deserialize to your object.
It will be good practice to expect required Object instead of creating objects from String.
Your Wrapper class will be like
public class SecurityDetailsWrapper {
private UserLogin;
private UserSecurityDetails;
// costructor
// getters and setters
}
in your Controller's method you can expect SecurityDetailsWrapper.
like
public void someFunction(#RequestBody SecurityDetailsWrapper wrapper) {
// business logic
}
Jackson will takes care of Deserialization.

Gson with dynamic name (Android)

I'm a beginner in java/Android and I try to parse JSON with Gson.
I'm having some difficulty with the files part.
From what I've read I should use MapHash but I'm not sure how to use it in this code
Here my Main class
InputStream source = retrieveStream(url);
Gson gson = new Gson();
Reader reader = new InputStreamReader(source);
SearchResponse response = gson.fromJson(reader, SearchResponse.class);
The class that do the parsing
public class SearchResponse {
public List<Podcast> podcasts;
class Podcast {
#SerializedName("files")
private List<File> files;
#SerializedName("format")
private String format;
#SerializedName("title")
private String title;
class File {
private String ValueX;
private String URLX;
}
}
}
json structure
{
"podcasts": [
{
"files": [
{"NameA": "ValueA"},
{"NameB": "ValueB"},
{"...": "..."}
],
"format": "STRING",
"title": "STRING"
}
]
}
Thanks for your help
here's an edited file of the structure of the JSon I try to parse
http://jsontest.web44.net/noauth.json
In your File class you have 2 attributes: ValueX and URLX. But in your JSON you have 2 fields NameA and NameB...
Names in JSON response and your class must match, otherwise you won't get any value...
Apart from that, your class structure looks good, and your code for deseralizing looks good as well... I don't think you need any HashMap...
EDIT: Taking into account your comment, you could use a HashMap. You could change your Podcast class using:
#SerializedName("files")
private List<Map<String,String>> files;
And you should get it parsed correctly.
You have to use a List because you have a JSON array (surrounded by [ ]), and then you can use the Map to allow different field names.
Note that you have to delete your File class...

Convert JSON String to Pretty Print JSON output using Jackson

This is the JSON string I have:
{"attributes":[{"nm":"ACCOUNT","lv":[{"v":{"Id":null,"State":null},"vt":"java.util.Map","cn":1}],"vt":"java.util.Map","status":"SUCCESS","lmd":13585},{"nm":"PROFILE","lv":[{"v":{"Party":null,"Ads":null},"vt":"java.util.Map","cn":2}],"vt":"java.util.Map","status":"SUCCESS","lmd":41962}]}
I need to convert the above JSON String into Pretty Print JSON Output (using Jackson), like below:
{
"attributes": [
{
"nm": "ACCOUNT",
"lv": [
{
"v": {
"Id": null,
"State": null
},
"vt": "java.util.Map",
"cn": 1
}
],
"vt": "java.util.Map",
"status": "SUCCESS",
"lmd": 13585
},
{
"nm": "PROFILE
"lv": [
{
"v": {
"Party": null,
"Ads": null
},
"vt": "java.util.Map",
"cn": 2
}
],
"vt": "java.util.Map",
"status": "SUCCESS",
"lmd": 41962
}
]
}
Can anyone provide me an example based on my example above? How to achieve this scenario? I know there are lot of examples, but I am not able to understand those properly. Any help will be appreciated with a simple example.
Updated:
Below is the code I am using:
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.defaultPrettyPrintingWriter().writeValueAsString(jsonString));
But this doesn't works with the way I needed the output as mentioned above.
Here's is the POJO I am using for the above JSON:
public class UrlInfo implements Serializable {
private List<Attributes> attribute;
}
class Attributes {
private String nm;
private List<ValueList> lv;
private String vt;
private String status;
private String lmd;
}
class ValueList {
private String vt;
private String cn;
private List<String> v;
}
Can anyone tell me whether I got the right POJO for the JSON or not?
Updated:
String result = restTemplate.getForObject(url.toString(), String.class);
ObjectMapper mapper = new ObjectMapper();
Object json = mapper.readValue(result, Object.class);
String indented = mapper.defaultPrettyPrintingWriter().writeValueAsString(json);
System.out.println(indented);//This print statement show correct way I need
model.addAttribute("response", (indented));
Below line prints out something like this:
System.out.println(indented);
{
"attributes" : [ {
"nm" : "ACCOUNT",
"error" : "null SYS00019CancellationException in CoreImpl fetchAttributes\n java.util.concurrent.CancellationException\n\tat java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:231)\n\tat java.util.concurrent.FutureTask.",
"status" : "ERROR"
} ]
}
which is the way I needed to be shown. But when I add it to model like this:
model.addAttribute("response", (indented));
And then shows it out in a resultform jsp page like below:
<fieldset>
<legend>Response:</legend>
<strong>${response}</strong><br />
</fieldset>
I get something like this:
{ "attributes" : [ { "nm" : "ACCOUNT", "error" : "null
SYS00019CancellationException in CoreImpl fetchAttributes\n
java.util.concurrent.CancellationException\n\tat
java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:231)\n\tat
java.util.concurrent.FutureTask.", "status" : "ERROR" } ] }
which I don't need. I needed the way it got printed out above. Can anyone tell me why it happened this way?
To indent any old JSON, just bind it as Object, like:
Object json = mapper.readValue(input, Object.class);
and then write it out with indentation:
String indented = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(json);
this avoids your having to define actual POJO to map data to.
Or you can use JsonNode (JSON Tree) as well.
The simplest and also the most compact solution (for v2.3.3):
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.writeValueAsString(obj)
The new way using Jackson 1.9+ is the following:
Object json = OBJECT_MAPPER.readValue(diffResponseJson, Object.class);
String indented = OBJECT_MAPPER.writerWithDefaultPrettyPrinter()
.writeValueAsString(json);
The output will be correctly formatted!
ObjectMapper.readTree() can do this in one line:
mapper.readTree(json).toPrettyString();
Since readTree produces a JsonNode, this should pretty much always produce equivalent pretty-formatted JSON, as it JsonNode is a direct tree representation of the underlying JSON string.
Prior to Jackson 2.10
The JsonNode.toPrettyString() method was added in Jackson 2.10. Prior to that, a second call to the ObjectMapper was needed to write the pretty formatted result:
mapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(mapper.readTree(json));
For Jackson 1.9, We can use the following code for pretty print.
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationConfig.Feature.INDENT_OUTPUT);
I think, this is the simplest technique to beautify the json data,
String indented = (new JSONObject(Response)).toString(4);
where Response is a String.
Simply pass the 4(indentSpaces) in toString() method.
Note: It works fine in the android without any library. But in java you have to use the org.json library.
You can achieve this using bellow ways:
1. Using Jackson
String formattedData=new ObjectMapper().writerWithDefaultPrettyPrinter()
.writeValueAsString(YOUR_JSON_OBJECT);
Import bellow class:
import com.fasterxml.jackson.databind.ObjectMapper;
It's gradle dependency is :
compile 'com.fasterxml.jackson.core:jackson-core:2.7.3'
compile 'com.fasterxml.jackson.core:jackson-annotations:2.7.3'
compile 'com.fasterxml.jackson.core:jackson-databind:2.7.3'
2. Using Gson from Google
String formattedData=new GsonBuilder().setPrettyPrinting()
.create().toJson(YOUR_OBJECT);
Import bellow class:
import com.google.gson.Gson;
It's gradle is:
compile 'com.google.code.gson:gson:2.8.2'
Here, you can also download correct updated version from repository.
This looks like it might be the answer to your question. It says it's using Spring, but I think that should still help you in your case. Let me inline the code here so it's more convenient:
import java.io.FileReader;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ObjectWriter;
public class Foo
{
public static void main(String[] args) throws Exception
{
ObjectMapper mapper = new ObjectMapper();
MyClass myObject = mapper.readValue(new FileReader("input.json"), MyClass.class);
// this is Jackson 1.x API only:
ObjectWriter writer = mapper.defaultPrettyPrintingWriter();
// ***IMPORTANT!!!*** for Jackson 2.x use the line below instead of the one above:
// ObjectWriter writer = mapper.writer().withDefaultPrettyPrinter();
System.out.println(writer.writeValueAsString(myObject));
}
}
class MyClass
{
String one;
String[] two;
MyOtherClass three;
public String getOne() {return one;}
void setOne(String one) {this.one = one;}
public String[] getTwo() {return two;}
void setTwo(String[] two) {this.two = two;}
public MyOtherClass getThree() {return three;}
void setThree(MyOtherClass three) {this.three = three;}
}
class MyOtherClass
{
String four;
String[] five;
public String getFour() {return four;}
void setFour(String four) {this.four = four;}
public String[] getFive() {return five;}
void setFive(String[] five) {this.five = five;}
}
Since jackson-databind:2.10 JsonNode has the toPrettyString() method to easily format JSON:
objectMapper
.readTree("{}")
.toPrettyString()
;
From the docs:
public String toPrettyString()
Alternative to toString() that will
serialize this node using Jackson default pretty-printer.
Since:
2.10
If you format the string and return object like RestApiResponse<String>, you'll get unwanted characters like escaping etc: \n, \". Solution is to convert your JSON-string into Jackson JsonNode object and return RestApiResponse<JsonNode>:
ObjectMapper mapper = new ObjectMapper();
JsonNode tree = objectMapper.readTree(jsonString);
RestApiResponse<JsonNode> response = new RestApiResponse<>();
apiResponse.setData(tree);
return response;
Anyone using POJO, DDO, or response class for returning their JSON can use spring.jackson.serialization.indent-output=true in their property file. It auto-formats the response.

Categories

Resources