I am trying to send JSON string to post method in order to receive flights information, i have the following json example i must modify to make different requests
{
"request": {
"passengers": {
"adultCount": 1
},
"slice": [
{
"origin": "BOS",
"destination": "LAX",
"date": "YYYY-MM-DD"
},
{
"origin": "LAX",
"destination": "BOS",
"date": "YYYY-MM-DD"
}
]
}
}
And i have the following class
public class Request {
public class Passengers{
private int adultCount;
public int getAdultCount() {
return adultCount;
}
public void setAdultCount(int adultCount) {
this.adultCount = adultCount;
}
}
private List<Slice> slice;
public List<Slice> getSlice() {
return slice;
}
public void setSlice(List<Slice> slice) {
this.slice = slice;
}
public static class Slice{
private String origin;
private String destination;
private String date;
public String getOrigin() {
return origin;
}
public void setOrigin(String origin) {
this.origin = origin;
}
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
}
}
how do i map this class to set the values and create a different json with the same format? i am trying with Jackson but im getting no suitable output
Here's the JSON format. Learn it well.
A JSON string maps to a Java String. A JSON number maps to a Java Number type. A JSON array maps to a Collection type or an array type. A JSON object maps to a Java Map type or any other Java type (not mentioned previously).
So a Java class like
class Foo {
String name;
int[] array;
Map<String, List<Double>> ref;
}
maps to
{
"name" : "string",
"array" : [1, 2, 3],
"ref" : {
"val1" : [1.2, 3.4]
}
}
Your JSON is a JSON object at the root. It contains
"request": {
which is a key value pair where the key is a JSON string and the value is a JSON object.
This should tell you that you need a Java object with a field named request which should be referencing another object. Do this analysis recursively and you will get your Java Object formats.
It would greatly simplify your life using Gson, a json library from google wich makes all parsing/encoding based o your class diagram. It also supports recursivity wich let you define more complex structures such arraylist, list, hashtable. Everything works by its self.
private String field = "field_1";
priavate String field2 = "field_2";
ArraList<FIELDS> field_list = new ArrayList<FIELDS>();
Would traduce to :
{
field : "field_1",
field2 : "field_2"
field_list : [
etc...
]
}
Related
i don't arrive to get the name of the containerStatuses.
I tried this (regarding a precedent post), the error is reported on the get("name") with "The method get(String) is undefined for the type JsonElement".
Thanks for help
JsonObject data = new Gson().fromJson(myjsoncontent, JsonObject.class);
JsonArray items = data .get("items").getAsJsonArray();
for(JsonElement element : items){
JsonObject object = element.getAsJsonObject();
String containerstatusesname = object.get("status").getAsJsonObject().get("containerStatuses").getAsJsonArray().get(0).get("name").getAsString();
}
// My Json Content
{
"kind": "Space",
"apiVersion": "v1",
"metadata": {
"selfLink": "something",
"resourceVersion": "something"
},
"items": [
{
"status": {
"containerStatuses": [
{
"name": "thisismyname"
}
]
}
}
]
}
Why are you using gson emulating JSON.parse? Is using a sledgehammer to crack a nut.
If you want to use gson it's better to create a class that matches your json data as:
public class ApiResponse {
private String kind;
private String apiVersion;
private Metadata metadata;
private List<Item> items;
public List<String> getAllNames() {
List<String> allNames = new ArrayList();
for (Item item: items) {
allNames.add(item.getStatus().get(0).getName());
}
return allNames;
}
public String getFirstName() {
if (items.length == 0 || items.get(0).getStatus().length == 0) {
return "";
}
return items.get(0).getStatus().get(0).getName();
}
class Metadata {
private String selfLink;
private String resourceVersion;
}
class Item {
private List<StatusContainer> status;
List<StatusContainer> getStatus() {
return status;
}
}
class StatusContainer {
private String name;
String getName() {
return name;
}
}
}
And then execute:
ApiResponse response = gson.fromJson(myjsoncontent, ApiResponse.class);
String firstName = response.getFirstName();
And this way the response object will contain all the data of the parsed json. Notice you'll need to add the getters to access this properties if are kept private.
No need to emulate the result of JSON.parse and have JsonObject, JsonArray...
You have to change
.get(0).get("name")
to
.get(0).getAsJsonObject().get("name")
JsonArray returns JsonElements when you iterate over it
Get the Array Element as Object cause its structured as Object
.getAsJsonArray().get(0).getAsJsonObject().get("name").getAsString();
I have a response that returns a json object in following format:
{
"playerId": "001",
"name": "michel",
"age": 21,
"nation": "USA",
"ratings": [
{
"type": "speed",
"score": "0121"
},
{
"type": "accuracy",
"score": "85"
}
],
"teaminfo": {
"teamName": "HON",
"isValid": "true"
}
}
and I have a Java Class as :
public class MyRider {
public String playerId;
public String name;
public int age;
public String speed;
public String accuracy;
public String teamName;
public String isValid;
//getter, setter...
}
I want to map the JSON object into Java object using GSON.
I tried using JsonDeserializationContext deserialize, and it returned null for the nested values in JSON.
Without custom deserializer
If you cannot change the JSON to return exactly what you want, I suggest you create classes to match it:
MyRider:
public class MyRider {
private String playerId;
private String name;
private int age;
private String nation;
private List<Rating> ratings;
private TeamInfo teaminfo;
// getters, setters, toString override
}
Rating:
public class Rating {
private String type;
private String score;
// getters, setters, toString override
}
TeamInfo:
private static class TeamInfo {
private String teamName;
private String isValid;
// getters, setters, toString override
}
Then simply deserialize as normal:
MyRider rider = gson.fromJson(json, MyRider.class);
If you need exactly the fields you've specified in MyRider in your question, consider a transformer class to map the full class above to your needs.
With custom deserializer
It's also possible to do this with a custom deserializer, but slightly pointless as GSON provides the normal mapping for you which you can then adapt.
Here is an example with a deserializer:
public class MyRiderDeserializer implements JsonDeserializer<MyRider> {
#Override
public MyRider deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context)
throws JsonParseException {
MyRider rider = new MyRider();
if(json.isJsonObject()) {
JsonObject riderObj = json.getAsJsonObject();
rider.setPlayerId(riderObj.get("playerId").getAsString());
rider.setName(riderObj.get("name").getAsString());
rider.setAge(riderObj.get("age").getAsInt());
JsonArray ratingsArray = riderObj.get("ratings").getAsJsonArray();
for(JsonElement ratingElem : ratingsArray) {
JsonObject ratingObj = ratingElem.getAsJsonObject();
String type = ratingObj.get("type").getAsString();
switch(type) {
case "speed":
rider.setSpeed(ratingObj.get("score").getAsString());
break;
case "accuracy":
rider.setAccuracy(ratingObj.get("score").getAsString());
break;
default:
break;
}
}
JsonObject teamInfo = riderObj.get("teaminfo").getAsJsonObject();
rider.setTeamName(teamInfo.get("teamName").getAsString());
rider.setIsValid(teamInfo.get("isValid").getAsString());
}
return rider;
}
}
Note this does not include any checks to validate whether the properties are actually there and is the simplest possible custom deserializer I could think of. To use it, you must register the type adapter at Gson creation time:
Gson gson = new GsonBuilder()
.registerTypeAdapter(MyRider.class, new MyRiderDeserializer())
.create();
MyRider myRider = gson.fromJson(reader, MyRider.class);
I've got an JSON string from my API, looks like this:
[
{
"id": "abc",
"data": {
"Name": "Peter",
"Date": "2017/12/01"
}
},
{
"id": "def",
"data": {
"Name": "Tina",
"Date": "2017/12/20"
}
},
{
"id": "ghi",
"data": {
"Name": "Amy",
"Date": "2017/12/16"
}
}
]
Then, I use (java):
Gson gson = new Gson();
Type resultType = new TypeToken<List<Map<String, Object>>>() {
}.getType();
List<Map<String, Object>> result = gson.fromJson(info, resultType);
if I call result.get(0).toString());
then it returned:
{id=abc, data={Name=Peter, Date=2017/12/01}}
if I call result.get(0).get("id").toString();
then it returned
abc
Now I want to get the data of "data", when I call result.get(0).get("data").toString();
then it returned
{Name=Peter, Date=2017/12/01}
Finally I want to get the "Name" info, but when I tried to convert this string to Map, it cause some problem, the code is like this:
Type type = new TypeToken<Map<String, Object>>(){}.getType();
Map<String, Object> myMap = gson.fromJson(str, type);
This doesn't work. I found that maybe the string is not a general type of JSON, it is like "Name=Peter, Date=2017/12/01", but it needs "Name": "Peter", "Date": "2017/12/01" , right? Is that the problem? How can I get the data of Name? Can anyone help me?
Updated:
I found that if "Name" = "", then I couldn't get it as string type, I cannot use "data.get("Name");". But I still need it. Anyone can fix it? Thanks.
You can directly convert the response into the POJO/Model class. Check this and this
You don't need manual parsing, if you are using Gson. See how-
List<Response> responseList = new Gson().fromJson(yourJson, new TypeToken<List<Response>>() {
}.getType());
Data data = responseList.get(0).getData();
String id = responseList.get(0).getId();
String date = data.getDate();
String name = data.getName();
Isn't this magic? No manual parsing at all.
Response.java class
public class Response {
private Data data;
private String id;
public void setData(Data data) {
this.data = data;
}
public Data getData() {
return data;
}
public void setId(String id) {
this.id = id;
}
public String getId() {
return id;
}
}
Data.java class
public class Data {
private String date;
private String name;
public void setDate(String date) {
this.date = date;
}
public String getDate() {
return date;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
How to generate Pojo classes? So here is several websites jsonschema2pojo. Also many Android Studio plugins available, I use RoboPOJOGenerator.
First of all, your JSON is malformed, it shouldn't have a comma after date.
and to answer your question, don't use map at all.
If you really want to do it without creating a model and additional classes, do it this way:
Gson gson = new Gson();
Type resultType = new TypeToken<List<JsonObject>>() {}.getType();
List<JsonObject> result = gson.fromJson(info, resultType);
System.out.println(result.get(0).get("data").toString());
JsonObject data = result.get(0).get("data").getAsJsonObject();
System.out.println(data.get("Name"));
i want to parse Json with this format:
{"data": {
"user": {
"edge_follow": {
"count": 2554, "page_info": {
"node": {
"id": "5719761315", "username": "disneyangell" ...
"node": {
"id": "2260368333", "username": "moosa_sedaghat",...
"node": {
"id": "3982701506", "username": "alidadashi512", ...
.
.
.
from this link ;
i got my pojos from www.jsonschema2pojo.org/
i tried GsonConverter and Jackson ObjectMapper also
the problem is parsed object's node list is empty or it's zero always.
how to solve this?
if i need to use CustomConverter write that for this case.
So to get the JSON you want you have to be logged in to instagiam. Otherwise you will get an empty "edges" object in the JSON returned from your get request. If you are logged in here is an example to do it with Gson:
The POJO (maybe you need to add getter methods for fields you are interested in):
public class FollowJson{
Data data;
String status;
public ArrayList<FollowNode> getFollowNodes(){
return data.getFollowNodes();
}
class Data{
User user;
public ArrayList<FollowNode> getFollowNodes(){
return user.getFollowNodes();
}
}
class User{
EdgeFollow edge_follow;
public ArrayList<FollowNode> getFollowNodes(){
return edge_follow.getFollowNodes();
}
}
class EdgeFollow{
Integer count;
ArrayList<OuterNode> edges;
HashMap<String, Object> page_info;
public ArrayList<FollowNode> getFollowNodes(){
ArrayList<FollowNode> bufList = new ArrayList<FollowNode>();
for(OuterNode outer : edges){
bufList.add(outer.getNode());
}
return bufList;
}
}
class OuterNode{
FollowNode node;
public FollowNode getNode(){
return node;
}
}
class FollowNode {
Boolean followed_by_viewer;
String full_name;
String id;
Boolean is_verified;
String profile_pic_url;
Boolean requested_by_viewer;
String username;
public Boolean getFollowedStatus(){
return followed_by_user;
}
public String getId(){
return id;
}
public String getUsername(){
return username;
}
}
}
Then pass the POJO.class and the JSON string to the Method:
public <T> T getJsonFromString(String jsonString, Class<T> var){
GsonBuilder builder = new GsonBuilder();
return builder.create().fromJson(jsonString, var);
}
You can then call getFollowNodes() on the returned object, which returns an array of objects (FollowNode) representing the "nodes" in the JSON.
I have a json object
data = {
'ad': {
"date":"2013-06-05",
"catagory":"6",
"subcatagory":"5",
"text":"John john",
"ssn":"1306743999",
"email":"jonbrynjar#365.is",
"phone":"8612001"
},
'cc-info': {
"amount": "70",
"cardNumber": "4222222222222",
"expiryDate": "1215",
"currency": "ISK"
},
'dates': [
{ 'date': '2013-06-18', 'media': 1 },
{ 'date': '2013-06-19', 'media': 3 }
]
}
Then I have a subflow that takes the "cc-info" part of that json object and uses that data to call a third party service.
To extract the "cc-info" part of the json object I use #JsonAutoDetect class
#JsonAutoDetect
public class Handpoint {
private String amount;
private String cardNumber;
private String expiryDate;
private String currency;
public String getAmount() { return this.amount; }
public void setAmount(String amount) { this.amount = amount; }
public String getCardNumber() { return this.cardNumber; }
public void setCardNumber(String cardNumber) { this.cardNumber = cardNumber; }
public String getExpiryDate() { return this.expiryDate; }
public void setExpiryDate(String expireDate) { this.expiryDate = expireDate; }
public String getCurrency() { return this.currency; }
public void setCurrency(String currency) { this.currency = currency; }
}
When I send in the whole json object I get an error.
The question is: Do I have to put every variable in the json object into my #JsonAutoDetect class ?
Or what would be best practice for this.
I have verified that my code works when I just send in the "cc-info" part of the json objcet.
You don't need that #JsonAutoDetect, it doesn't do anything different from defaults without arguments.
But if your question is whether you can just ignore unknown properties, answer is yes. Here are couple of ways.
For example:
mapper.disable(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES);
would do the trick.
There is an easier way to convert your JSON element to a series of objects. Have you tried the Google GSon library? There is a sample:
import com.google.gson.Gson;
Gson gson = new Gson();
Handpoint testing = gson.fromJson(data, Handpoint.class);
System.out.println("Amount: " + testing.getAmount());
On the other hand, if you want to deserialize the dates, that contain arrays, you'd better take a look here:
Gson Array deserialization