Receive JSON data from a webservice using REST API - java

I need to receive JSON data from this Api http://countryapi.gear.host/v1/Country/getCountries using REST API. I need to receive NativeName and Region for the specific country.
My main problem is how to send request for the specific country (for example I print Name Australia) and get the response for NativeName and Region - Australia, Oceania (it should be String).
I have such classes:
public class Client {
public static void main(String[] args) throws ClientProtocolException, IOException {
HttpClient clientGetEntity = new DefaultHttpClient();
HttpGet request = new HttpGet("http://countryapi.gear.host/v1/Country/getCountries?pName=Australia");
request.addHeader("accept", "application/json");
HttpResponse responseGetEntity = clientGetEntity.execute(request);
//String json =EntityUtils.toString((HttpEntity) responseGetEntity);
System.out.println("Request : " + request.toString());
System.out.println("Response : " + responseGetEntity.toString());
}
}

EDITS
As regards getting the specific country's name, you need to make a get request with the country name such as:
http://countryapi.gear.host/v1/Country/getCountries?pName=Australia
The response from this request:
{
"IsSuccess": true,
"UserMessage": null,
"TechnicalMessage": null,
"TotalCount": 1,
"Response": [
{
"Name": "Australia",
"Alpha2Code": "AU",
"Alpha3Code": "AUS",
"NativeName": "Australia",
"Region": "Oceania",
"SubRegion": "Australia and New Zealand",
"Latitude": "-27",
"Longitude": "133",
"Area": 7692024,
"NumericCode": 36,
"NativeLanguage": "eng",
"CurrencyCode": "AUD",
"CurrencyName": "Australian dollar",
"CurrencySymbol": "$",
"Flag": "https://api.backendless.com/2F26DFBF-433C-51CC-FF56-830CEA93BF00/473FB5A9-D20E-8D3E-FF01-E93D9D780A00/files/CountryFlags/aus.svg",
"FlagPng": "https://api.backendless.com/2F26DFBF-433C-51CC-FF56-830CEA93BF00/473FB5A9-D20E-8D3E-FF01-E93D9D780A00/files/CountryFlagsPng/aus.png"
}
]
}
You can access NativeName and region by:
data.Response[0].NativeName and data.Response[0].Region respectively.
Since the data returned from the API is always a JSON string, dont forget to parse the string before use.
----------------------------------------
I am not a java developer but I have dealt with a lot of JSON data, Also C# and TypeScript projects.
First, you should take a look at this line:
request.addHeader("accept", "application/fson");
Am afraid this is not a valid JSON request header and if we where to start debugging your code, it would be difficult to pinpoint where the problem lies if the basis of the whole request is faulty. Please correct to:
request.addHeader("accept", "application/json"); and try again, if you have the same result, we can continue debugging from there.

Related

Rest web services(post) consumes json not working

So I am trying to create a simple webservice post that consumes json. But I am geting the error RESTEASY002010: Failed to execute: javax.ws.rs.NotSupportedException: RESTEASY003065: Cannot consume content type
My webservice:
#POST
#Produces(MediaType.APPLICATION_XML)
#Path("teste1")
#Consumes(MediaType.APPLICATION_JSON)
public Response teste1(String product) {
String result = "Product created : " + product;
System.out.println("resultado");
System.out.println(result);
return Response.ok() //200
.entity("<erro> none </erro>")
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
.header("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With").build();
}
I also tried to do:
#Consumes("application/json")
But I am getting the same error. I can make it work if I do:
#Consumes("*/*")
But I can't understand why it doesn't work when I say it consumes json. To test the webservice I am using https://apitester.com/. With the folowing Post Data:
{
"key" : "value",
"array" : [
{ "key" : 1 },
{ "key" : 2, "dictionary": {
"a": "Apple",
"b": "Butterfly",
"c": "Cat",
"d": "Dog"
} },
{ "key" : 3 }
]
}
In general the
#Consumes("application/json")
specifies a content media type which webservice can handle.
But also you may need to explicitly specify an appropriate type in the Content-Type header for your request.
I am not familiar with the https://apitester.com but probably it does not send the Content-Type header by default
In such case your server can treat the request body as a plain text, for instance. That request would not be routed to your endpoint, because it is not designed for the plain text.
Setting the #Consumes(*/*) fixes that problem, because the wrong media type matches that pattern as well.
Could you please ensure that you sends the Content-Type: application/json with your POST request?

How to convert value with unicode in Json request into simple characters?

Sometime client send Json-RPC request with Json value as unicorde symboles.
Example:
{ "jsonrpc": "2.0", "method": "add", "params": { "fields": [ { "id": 1, "val": "\u0414\u0435\u043d\u0438\u0441" }, { "id": 2, "val": "\u041c\u043e\u044f" } ] }, "id": "564b0f7d-868a-4ff0-9703-17e4f768699d" }
How do I processing Json-RPC request:
My server get the request like byte[];
Convert it to io.vertx.core.json.JsonObject;
Make some manipulations;
Save to DB;
And I found in DB records like:
"val": "\u0414\u0435\u043d\u0438\u0441"
And the worst in this story. If client try to search this data, he'll get:
"val": "\\u0414\\u0435\\u043d\\u0438\\u0441"
So I think, that I need to convert request data before deserialization to JsonObject.
I tried and it didn't help:
String json = new String(incomingJsonBytes, StandardCharsets.UTF_8);
return json.getBytes(StandardCharsets.UTF_8);
Also I tried to use StandardCharsets.US_ASCII.
Note: Variant with StringEscapeUtils.unescapeJava() I can not, because it unescape all necessary and unnecessary '\' symbols.
If anyone know how to solve it? Or library that already makes it?
Thank a lot.
io.vertx.core.json.JsonObject depends on Jackson ObjectMapper to perform the actual JSON deserialization (e.g. io.vertx.core.json.Json has a ObjectMapper field). By default Jackson will convert \u0414\u0435\u043d\u0438\u0441 into Денис. You can verify this with a simple code snippet:
String json = "{ \"jsonrpc\": \"2.0\", \"method\": \"add\", \"params\": { \"fields\": [ { \"id\": 1, \"val\": \"\\u0414\\u0435\\u043d\\u0438\\u0441\" }, { \"id\": 2, \"val\": \"\\u041c\\u043e\\u044f\" } ] }, \"id\": \"564b0f7d-868a-4ff0-9703-17e4f768699d\" }";
ObjectMapper mapper = new ObjectMapper();
Map map = mapper.readValue(json, Map.class);
System.out.println(map); // {jsonrpc=2.0, method=add, params={fields=[{id=1, val=Денис}, {id=2, val=Моя}]}, id=564b0f7d-868a-4ff0-9703-17e4f768699d}
Most likely the client is sending something else because your example value is deserialized correctly. Perhaps it's doubly escaped \\u0414\\u0435\\u043d\\u0438\\u0441 value which Jackson will convert to \u0414\u0435\u043d\u0438\u0441 removing one layer of escaping?
There is no magic solution for this. Either write your own Jackson deserialization configuration or make the client stop sending garbage.

Get all records from JSON response

I'm still kind of new to the Rest Assured API world. I've read through as much documentation on https://github.com/rest-assured/rest-assured/wiki/Usage#example-3---complex-parsing-and-validation as I can stand.
I have a response that looks like:
{
"StatusCode": 200,
"Result": [
{
"EmployeeId": "5661631",
"PhoneTypeDescription": "Home",
"PhoneNumber": "9701234567",
},
{
"EmployeeId": "5661631",
"PhoneTypeDescription": "mobile1",
"PhoneNumber": "2531234567",
},
{
"EmployeeId": "5661631",
"PhoneTypeDescription": "mobile2",
"PhoneNumber": "8081234567",
}
]
}
I've been struggling with how to get just the first record's PhoneNumber.
String responseBody=
given()
.relaxedHTTPSValidation().contentType("application/json")
.param("api_key", api_key).
when()
.get("/api/employees/" + employeeId)
.andReturn().asString();
JsonPath jsonPath = new JsonPath(responseBody).setRoot("Result");
phoneNumber = jsonPath.getString("PhoneNumber");
I get all the phone numbers in this case:
phoneNumber = "[9701234567,2531234567,8081234567]"
How can I get just the first record? I'd rather not have to perform string operations to deal with the, "[".
Thanks
You can simply do,
JSONObject json = new JSONObject(responseBody);
phoneNumber = json.getJSONArray("Result").getJSONObject(0).getString("PhoneNumber");
Here, 0 indicates the first record in the JSON Array Result.
Because you know the index of the element you want to retrieve, you can use the following code:
JsonPath jsonPath = new JsonPath(response);
String phoneNumber = jsonPath.getString("Result[0].PhoneNumber");

Extracting text from Http response

following is the screenshot of http respone in java -
and following is the text form of response:
{
"LightGingerTheTextResult": [
{
"Confidence": 4,
"From": 0,
"LrnFrg": null,
"LrnFrgOrigIndxs": [],
"Mistakes": [
{
"CanAddToDict": false,
"From": 0,
"To": 0
}
],
"ShouldReplace": true,
"Suggestions": [
{
"LrnCatId": 12,
"Text": "An"
},
{
"LrnCatId": 45,
"Text": "A"
}
],
"To": 0,
"TopLrnCatId": 12,
"Type": 3,
"UXFrgFrom": 0,
"UXFrgTo": 6
}
]
}
I want to extract the "text" in the suggestion.
This is my part with json. I am getting final response in "finalResult"-
JSONObject json = new JSONObject();
try
{
StringBuffer response =urllib.urlopen(url);
String finalResponse= response.toString();
System.out.println("final response"+finalResponse);
StringBuffer result=(StringBuffer) json.get(finalResponse);
//finalResult=URLEncoder.encode(result.toString(), "UTF-8");
String finalResult=result.toString();
}
catch (Exception e) {
System.out.println(e.getMessage());
}
See stackoverflow.com/questions/2591098. You needs a library,
using package org.json with
new JSONObject(textOfResponse)
.getJSONArray("LightGingerTheTextResult").getJSONObject(0)
.getJSONArray("Suggestions").getJSONObject(0)
.getString("Text")
and your textOfResponse I get
An
If you are looking for a value of a specific JSON node you can use a JsonPath expression e.g. to extract values of all Text nodes:
$.LightGingerTheTextResult[*].Suggestions[*].Text
in your example simplifies to
$..Text
or just the first Text node from the first Suggestions node:
$.LightGingerTheTextResult[0].Suggestions[0].Text
I would suggest you to first start by retreive the body of your httpResponse object.
String tmp = response.body(); // I assume the callback method has a an
//argument of type
//httpResponse called response
Then store it somewhere eg:string.
Use gson and use the httpResponse class
like this:
httpResponse rep = gson.fromJson(, httpResponse .class);
This way you can now use the rep object to retreive what ever you want.

How to get Total Sleep from Google Fit REST API

I tried this using java
String AccessToken = "TOKEN";
String ApiUrl = "https://www.googleapis.com/fitness/v1/users/me/sessions?startTime=2017-02-28T22:00:00.00Z&endTime=2017-03-01T10:59:59.99Z";
HttpClient httpclient = HttpClientBuilder.create().build();
try {
HttpGet httpPost = new HttpGet(ApiUrl);
httpPost.addHeader("Authorization", "Bearer " + AccessToken);
HttpResponse response = httpclient.execute(httpPost);
`enter code here` System.out.println("\nSending 'GET' request to URL : " + ApiUrl);
HttpEntity entity = response.getEntity();
BufferedReader rd = new BufferedReader(
new InputStreamReader(entity.getContent()));
String line;
while ((line = rd.readLine()) != null) {
System.out.println("line" + line);
}
} catch (Exception e) {
System.out.println("Exception at getDataFromUrl ,error is " + e.getMessage());
}
And I am getting response like
{
"session": [
{
"id": "Deep sleep141488319560000",
"name": "Deep sleep14",
"startTimeMillis": "1488319560000",
"endTimeMillis": "1488320700000",
"modifiedTimeMillis": "1488374094270",
"application": {
"packageName": "com.xiaomi.hm.health"
},
"activityType": 72
},
{
"id": "Deep sleep161488321420000",
"name": "Deep sleep16",
"startTimeMillis": "1488321420000",
"endTimeMillis": "1488322500000",
"modifiedTimeMillis": "1488374094280",
"application": {
"packageName": "com.xiaomi.hm.health"
},
"activityType": 72
},
{
"id": "Deep sleep201488328680000",
"name": "Deep sleep20",
"startTimeMillis": "1488328680000",
"endTimeMillis": "1488330360000",
"modifiedTimeMillis": "1488374094303",
"application": {
"packageName": "com.xiaomi.hm.health"
},
"activityType": 72
},
{
"id": "Light sleep131488318900000",
"name": "Light sleep13",
"startTimeMillis": "1488318900000",
"endTimeMillis": "1488319560000",
"modifiedTimeMillis": "1488374094265",
"application": {
"packageName": "com.xiaomi.hm.health"
},
"activityType": 72
}]}
But i want get total sleep e.g 7 hours 10 mins
Is it correct API I am using or am i missing something.
Any help appreciated. I am new to Google Fit.
Note:This is java not Android.
You must calculate the sleep duration on your own by computing the difference between "endTimeMillis" and "startTimeMillis" and summerize these computed values in your requested range. That’s easy, but also tricky as the stored data may differ from the source (the app that sends the data to google fit).
I also run in this issue and did not find a satisfying solution yet that is working correct. Since sleep data it is not a "real" data type (see https://developers.google.com/fit/rest/v1/data-types#public_data_types) you cannot be sure that an app sends duplicate values within the same requested range. In my case the app "xiaomi mi-fit" sends duplicate values with the same "startTimeMillis" and "endTimeMillis" so you must check this in your code. Otherwise you will be getting a sleep duration that is not accurate.
As long as Google did not support sleep data as an official data type you cannot be sure that the data is correct. Moreover: When different apps send their sleep data to the same google fit account the data will not be aggregated, you will have to sort this on your own by filtering the package name (app) that sends the data.
Also, Google removed the visibility of sleep data in their own native app (version 2.x) and in their WebView (https://fit.google.com) too!

Categories