I'm new to JSON handling with retrofit but I've run into a problem.
We're making a prototype smart assistant chatbot with Dialogflow.
My Android Client sends a POST request to Google Dialogflow, which will call third party API's and send a response back.
However, this response depends on the type of intent detected by Dialogflow.
It can be nearly everything from music to weather information etc.
So the parameters (for the visualization) will be completely different and I don't know the type of response in advance.
I preprocess the response from Dialogflow in my own cloud function and send it back containing only the necessary fields for the client.
For example:
"What is the weather today in Brussels?"
Response:
{
"sessionId": "123456789",
"keepAlive": true,
"intentId": 100,
"intentName": "Weer",
"text": "Het weer in Hanoi is helder met een temperatuur van 23.2 graden.",
"Parameters": {
"text": {
"stringValue": "helder",
"kind": "stringValue"
},
"city": {
"stringValue": "Hanoi",
"kind": "stringValue"
},
"temp": {
"numberValue": 23.2,
"kind": "numberValue"
},
"intentId": {
"numberValue": 100,
"kind": "numberValue"
}
}
}
You can see the Parameters of the response depend on the type of intent(id). there can be many or zero parameters depending on the intent.
How can I make a Pojo for every type of response, not only the weather?
Or can I make a switch case based on intentId or something?
You can use generics than
public class Response<T> {
private String responseId;
private String sessionId;
private boolean keepAlive;
private float intentId;
private String intentName;
private String text;
private String Audio;
private T Parameters;
}
and when you want to create the object you can
new Response<YourClass>();
Your class will be the class as per your intent id
Related
My requirement is to store credit card details in Paypal vault using Android.
I followed these link
https://github.com/paypal/PayPal-Java-SDK
https://github.com/paypal/PayPal-Android-SDK
https://developer.paypal.com/docs/integration/direct/rest-vault-overview/
there is no mention on how to vault a credit using Android sdk. I think it can be done using their Rest API. How do I achieve this in Android?
You can store credit card in paypal using vault api Follow this steps
Step 1: Generate Access Token By OAuth Token Request
Try in postman
Url :- https://api.sandbox.paypal.com/v1/oauth2/token
Headers :- (Key,Value)
1.(Accept , application/json)
2.(Accept-Language , en_US)
3.(Content-Type , application/x-www-form-urlencoded)
4.(Authorization , Basic<Space>(here your code generated by postman))
Note :- Generate a Basic Auth in post man by select authorization tab ==> Basic Auth and enter paypal Client secret and Client id.
Body :- (Key,Value)
1.(grant_type,client_credentials)
Note :- Select x-www-form-urlencoded in body tab in postman
Step 2: Store credit card using valut api
Try in postman
Url :- https://api.sandbox.paypal.com/v1/vault/credit-cards
Headers :- (Key,Value)
1.(Accept , application/json)
2.(Accept-Language , en_US)
3.(Content-Type , application/x-www-form-urlencoded)
4.(Authorization , Bearer(your Access Token))
Body : (Json)
{
"payer_id": "user12345",
"type": "visa",
"number": "4111111111111111",
"expire_month": "11",
"expire_year": "2018",
"first_name": "Joe",
"last_name": "Shopper",
"billing_address": {
"line1": "52 N Main ST",
"city": "Johnstown",
"state": "OH",
"postal_code": "43210",
"country_code": "US"
}
}
Note :- Select raw tab in body in postman.
Thanks to vishal for his help. I was able to solve this using retrofit (adding headers statically).
1. First get the value of your authorization header:
String clientId = "your client id";
String clientSecret = "your client secret";
String credentials = clientId + ":" + clientSecret;
String basic =
"Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
Log.e("Authorization",basic);
Copy this value from log, it will be used later in our solution.
2. Make the response model according to this json:
{
"scope":"https://api.paypal.com/v1/payments/.* https://api.paypal.com/v1/vault/credit-card https://api.paypal.com/v1/vault/credit-card/.*",
"access_token":"Access-Token",
"token_type":"Bearer",
"app_id":"APP-6XR95014SS315863X",
"expires_in":28800
}
3. Make retorfit call method as this:
#Headers({
"Accept: application/json",
"Accept-Language : en_US",
"Content-Type : application/x-www-form-urlencoded",
"Authorization:your basic string value here"
})
#POST("https://api.sandbox.paypal.com/v1/oauth2/token/")
Call<AuthenticationTokenModel> getAuthentionToken(#Query("grant_type") String grant_type);
4. Finally make the call as:
ApiInterface apiInterface= ApiClient.getClient().create(ApiInterface.class);
apiInterface.getAuthentionToken("client_credentials").enqueue(new Callback<AuthenticationTokenModel>() {
#Override
public void onResponse(Call<AuthenticationTokenModel> call, Response<AuthenticationTokenModel> response) {
Log.e("response",response.body().getAccess_token());
}
#Override
public void onFailure(Call<AuthenticationTokenModel> call, Throwable t) {
Log.e("response",t.getMessage());
}
});
Thanks.
Edited:
You can also add dynamic headers to requests in Retrofit 2.
Follow this:
https://futurestud.io/tutorials/retrofit-add-custom-request-header
i have problems i am searching and cant understand what type of json parser i can use for example i have local json and i want to prase it is there any sdk i can use near the newsoft json or ez to learn because i am windows phone and 8.1 developer and i sucks with android and i really need it for graduation project i created almost every thing
[
{
"id": 1,
"time": 40,
"srcLong": 35.909124,
"srcLat": 31.973628,
"destLong": 35.898258,
"destLat": 31.985622,
"subSites": [
{
"id": 1,
"name": "location 1"
},
{
"id": 2,
"name": "location 2"
},
{
"id": 3,
"name": "location 3"
}
]
}]
plz how to get the response for example the code in newsoft json is like this
var serviceUri = "http://localhost:24728/api/sites";
HttpClient client = new HttpClient();
var response = await client.GetAsync(serviceUri);
var datafile = await response.Content.ReadAsStringAsync();
RootObject data = JsonConvert.DeserializeObject<RootObject (((string)datafile).Substring(1, ((string)datafile).Length - 2));
and of course you create the class to deal with object plz can some one help me with this and i need to remove the [] to be json object i just need the sdk i should use and where to start learn and if there no problem to tell me how to substring it and to put this code
string uri = "http://localhost:24728/api/sites/1";
HttpResponseMessage response2 = await client.PutAsJsonAsync(uri, data);
plz is there any equivalent in android.
Regards,
Ayesh.
Well from what you are saying it looks like you are unsure of how to get a response from the site, maybe you do not understand how to access the url initially. Or potentially that once you get the response and it is prehaps a string you do not know how to convert it into JSON to extract the information. Send information from android application to a Web Service and back. This link has a basic version of connecting to a url. And when you have a string, you can use JSONObject and JSONArrays to grab the information on that string, you can do JSONArray(string).
Normally RESTful end point returns one object or a list of said type object with some additional data for pagination purposes.
However, interesting case, the API I am working with will return a list of mixed type objects. For example:
{
"media": [
{
"id": 1,
"type": "oranges",
"Some type specific property": "foo"
},
{
"id": 1,
"type": "apples",
"Some type specific property": "bar"
}
]
}
Is it possible for retrofit to accommodate this with reflection and properly pick out the different type of objects returned with the same key? (As in our example media)
The mobile application is already running in production mode, and what would be the least painful way to accommodate this API architecture?
use http://www.jsonschema2pojo.org/ to create java object models
define your api using retrofit
public interface sampleApi {
#GET("/v1/endpoint")
void promoImages(Callback<CustomObject> callback);
Create Adapter
RestAdapter.Builder builder = new RestAdapter.Builder()
.setEndpoint(BuildConfig.BASE_SERVER_ENDPOINT)
.setClient(new OkClient(client));
CustomApi api = builder.build().create(CustomApi.class);
Call api
api.promoImages(callback);
I'm trying to build the following JSON Request Body.
It's my first time with JSON and I'm following this examples, but still struggling.
I've been taking a look to GSON but wanted to manage pure JSON first, and maybe for something so small it's not worth it to add GSON library?
Could you help me with the code?
Thanks.
{
locations:
[
{
latLng:
{
lat: 40.900799,
lng: 8.606102
}
},
{
latLng:
{
lat: 42.900799,
lng: 9.606102
}
}
]
}
EDIT:
Here is the Web Service I am trying to consume and here a request sample.
Use json objects.
Do something like that.
Don't write json by hand, you could easily do a mistake.
public JSON() throws JSONException
{
JSONArray locArr=new JSONArray();
locArr.put(createLatLng(40.900799, 8.606102));
locArr.put(createLatLng(42.900799, 9.606102));
JSONObject main=new JSONObject();
main.put("locations", locArr);
Log.d("JSON",main.toString());
}
public JSONObject createLatLng(double lat, double lng) throws JSONException
{
JSONObject latLng=new JSONObject();
latLng.put("lat",lat);
latLng.put("lon",lng);
JSONObject latLngWrap=new JSONObject();
latLngWrap.put("latLng",latLng);
return latLngWrap;
}
JSON notation requires the "" around field names. Values should only be wrapped, if they are string.
{
"locations":
[
{
"latLng":
{
"lat": 40.900799,
"lng": 8.606102
}
},
{
"latLng":
{
"lat": 42.900799,
"lng": 9.606102
}
}
]
}
You can always verify, if you JSON is correct using
http://jsonlint.com/
Expanding on maciekczwa's answer. JSON (unlike arguably XML) isn't really meant to be looked at with human eyes. It very quickly becomes very hard to see where one object starts and ends and what's wrapping what. Use his example to create your main JSON object and then fill it with whatever objects you need to. When you're all done you can convert it to string for transport very easily, without having to look at it, and doing it this way means not having to worry about what labels need to be wrapped in what kinds of quotes etc.
And eskalera is 100% correct. JSON requires all fields to be wrapped in quotes (the rules around whether or not they can be single quotes or *MUST be double quotes vary from implementation to implementation, but again, this is only relevant if you're constructing the JSON manually, as you should only do in instances where it's EXTREMELY simple (and even then... probably not).
{
"serviceType":"IMAGE_ANDROID",
"parameters":[
[
{
"itemId":"it003376",
"itemNameInEng":"8th Chennai International Film Festival Photos",
"itemSmallImage":"http://122.183.217.134:8080/sivajitv/photos/20101216001017.jpg",
"count":"110"
},
{
"itemId":"it003375",
"itemNameInEng":"Actress Aishwarya Rai Special Photos",
"itemSmallImage":"http://122.183.217.134:8080/sivajitv/photos/20101215230917.jpg",
"count":"7"
},
{
"itemId":"it003374",
"itemNameInEng":"Actor Srikanth Flag off The Avon Greenathon Bicycle Rally ",
"itemSmallImage":"http://122.183.217.134:8080/sivajitv/photos/20101215212620.jpg",
"count":"43"
},
{
"itemId":"it003373",
"itemNameInEng":"Kadamai Kanniyam Kattupadu Movie Launch Photos",
"itemSmallImage":"http://122.183.217.134:8080/sivajitv/photos/20101213001908.jpg",
"count":"32"
},
{
"itemId":"it003372",
"itemNameInEng":"Kanden Audio Launch Photos",
"itemSmallImage":"http://122.183.217.134:8080/sivajitv/photos/20101210044334.jpg",
"count":"126"
}
]
]
}
this is my response
i want to parse the parameters from this response and i need to parse all data in parameter
please provide me correct solution
Make use of JSONArray class in org.json.JSONArray..
see this link
Accessing members of items in a JSONArray with Java
Use the org.json classes in the SDK.