confused sending json as a parameter - java

I've the below java program that prints a json string.
System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(objectsToSerialise));
I tried to find the type of objectsToSerialise with the below line of code.
System.out.println(objectsToSerialise.getClass().getTypeName());
this returned java.util.ArrayList
the output that I get is as below.
[ {
"EntityLabels" : [ {
"StartToken" : 8,
"EntityType" : "Personname",
"EndToken" : 16
}, {
"StartToken" : 24,
"EntityType" : "Amount::Spent",
"EndToken" : 31
} ],
"ExampleText" : "What is Frede's limit? ",
"SelectedIntentName" : "GiftLimit"
} ]
And I'm trying to post the same to my API . And the code is as below.
And luisUrl ="https://westus.api.cognitive.microsoft.com"
HttpPost httpPost = new HttpPost(luisUrl + "/luis/v1.0/prog/apps/" + appId + "/examples?");
httpPost.setHeader("Ocp-Apim-Subscription-Key", subsriptionId);
StringEntity params = new StringEntity(objectsToSerialise.toString());
httpPost.setHeader("Content-Type", "application/json");
httpPost.setEntity(params);
HttpResponse response = httpclient.execute(httpPost);
/* Debug Info */
System.out.println("---------------Start2----------------");
HttpEntity entity = response.getEntity();
String responseString = EntityUtils.toString(entity, "UTF-8");
System.out.println(responseString);
System.out.println("---------------End----------------");
/*End Debug Info*/
if (response.getStatusLine().getStatusCode() == 201) {
success = true;
System.out.println("Success");
} else {
System.out.println("Block");
success = false;
}
And this is always printing else content. i.e. Block. I thought this might be an issue with my calling and tried the same in Postman. with the below details.
URL:https://westus.api.cognitive.microsoft.com/luis/v1.0/prog/apps/{appId}/examples?
Method: post
Headers:
Content-Type:application/json
Ocp-Apim-Subscription-Key:{mySubscriptionKey}
Body:**raw->JSON
**Content:
[ {
"EntityLabels" : [ {
"StartToken" : 8,
"EntityType" : "Personname",
"EndToken" : 16
}, {
"StartToken" : 24,
"EntityType" : "Amount::Spent",
"EndToken" : 31
} ],
"ExampleText" : "What is Frede's limit? ",
"SelectedIntentName" : "GiftLimit"
} ]
To my surprise, when I post this, it is returning me 201, where as my Java code is returning me 400.
This is very confusing. Please let me know where am I going wrong and how can I fix this.
Thanks

objectsToSerialize seems to be an ArrayList, but in your code you construct request body with new StringEntity(objectsToSerialise.toString());. That is, you don't convert your ArrayList to JSON, but instead you just get its string representation which is not a JSON usually.
Try changing
new StringEntity(objectsToSerialise.toString());
to
new StringEntity(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(objectsToSerialise));

Related

Unable to List Item via EBay's Inventory API

I'm attempting to list an item on EBay using EBay's Inventory API via the following code (I'm using Apache HTTP Client):
public void put() throws ClientProtocolException, IOException
{
String url = "https://api.ebay.com/sell/inventory/v1/inventory_item/83368339";
String charset = "utf-8";
HttpClient client = HttpClientBuilder.create().build();
HttpPut put = new HttpPut(url);
// add request header
put.addHeader("Authorization", "Bearer <TOKEN>");
put.addHeader("Content-Language", "en-US");
String json = "{ \"availability\": { \"pickupAtLocationAvailability\": [ { \"availabilityType\": \"IN_STOCK\", \"fulfillmentTime\": { \"unit\": \"TimeDurationUnitEnum\": \"BUSINESS_DAY\", \"value\": 1 }, \"merchantLocationKey\": \"NJ\", \"quantity\": 1 } ], \"shipToLocationAvailability\": { \"quantity\": 1 } }, \"condition\": \"ConditionEnum : [NEW]\", \"conditionDescription\": \"New condition\","
+ "\"product\": { \"aspects\": \"object\", \"brand\": \"Outlite\", \"description\": \"ADJUSTABLE FOCUS: Intense Spotlight for long range observation can up to 600 feet, Circle Floodlight for large area illumination\", \"imageUrls\": [ \"https://images-na.ssl-images-amazon.com/images/I/71c57aJiDAL._SL1500_.jpg\" ], \"title\": \"Outlite A100 Portable Ultra Bright Handheld LED Flashlight\", \"sku\": \"sku546372817\" }";
HttpResponse response = client.execute(put);
System.out.println("Response Code : "
+ response.getStatusLine().getStatusCode());
BufferedReader rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line);
}
System.out.println(result);
}
However I'm encountering the following error:
Response Code : 400
{"errors":[{"errorId":2004,"domain":"ACCESS","category":"REQUEST","message":"Invalid request","longMessage":"The request has errors. For help, see the documentation for this API.","parameters":[{"name":"reason","value":"Could not serialize field [availability.pickupAtLocationAvailability.availabilityType]"}]}]}
From the comments above, there were a few issues:
Remove the surrounding parentheses
Remove the surrounding quotes around the JSON
Enum formatting
After the last comment and confirming that removing the square brackets might have cleared up the availabilityType enum issue, here's what I think your final JSON should look like:
String json = "{ \"availability\": { \"pickupAtLocationAvailability\": [ { \"availabilityType\": \"IN_STOCK\", \"fulfillmentTime\": { \"unit\": \"BUSINESS_DAY\", \"value\": 1 }, \"merchantLocationKey\": \"NJ\", \"quantity\": 1 } ], \"shipToLocationAvailability\": { \"quantity\": 1 } }, \"condition\": \"NEW\", \"conditionDescription\": \"New condition\","
+ "\"product\": { \"aspects\": \"object\", \"brand\": \"Outlite\", \"description\": \"ADJUSTABLE FOCUS: Intense Spotlight for long range observation can up to 600 feet, Circle Floodlight for large area illumination\", \"imageUrls\": [ \"https://images-na.ssl-images-amazon.com/images/I/71c57aJiDAL._SL1500_.jpg\" ], \"title\": \"Outlite A100 Portable Ultra Bright Handheld LED Flashlight\", \"sku\": \"sku546372817\" }}";
Here it is split out into non-Java escapedness:
{
"availability": {
"pickupAtLocationAvailability": [{
"availabilityType": "IN_STOCK",
"fulfillmentTime": {
"unit": "BUSINESS_DAY",
"value": 1
},
"merchantLocationKey": "NJ",
"quantity": 1
}],
"shipToLocationAvailability": {
"quantity": 1
}
},
"condition": "NEW",
"conditionDescription": "New condition",
"product": {
"aspects": "object",
"brand": "Outlite",
"description": "ADJUSTABLE FOCUS: Intense Spotlight for long range observation can up to 600 feet, Circle Floodlight for large area illumination",
"imageUrls": ["https://images-na.ssl-images-amazon.com/images/I/71c57aJiDAL._SL1500_.jpg"],
"title": "Outlite A100 Portable Ultra Bright Handheld LED Flashlight",
"sku": "sku546372817"
}
}
I modified the fulfillmentTime.unit and condition enums as well. It also looks like you might've been missing an a closing curly bracket at the end, so I added that as well.

Formatting Json Code in Java

I need to convert the following Json code into Java.
{
"service": {
"type": "nyd",
"discount": 0.20,
"items": [
{
"asin": "....",
"link": "http://amazon.com/.....",
"quantity": 2
},
// ...
],
// See /addresses
"shipping_address": {
"full_name": "Mr Smith",
"street1": "Some Mission St",
"street2": "", // Optional
"city": "San Francisco",
"state": "CA",
"zip": "94000",
"country": "US",
"phone": "1234567890"
}
}
}
I'm currently implementing this by using the following code:
String postUrl = "https://API.example.com";
Gson gson = new Gson();
HttpClient httpClient = HttpClientBuilder.create().build();
HttpPost httpPostRequest = new HttpPost(postUrl);
StringEntity postingString = new StringEntity("{\"service\" : {\"type\":\"nnn\", \"discount\":" + 0.2 + ",\"items\" : [ { \"asin\":\"B018Y1XXT6\", \"link\":\"https://www.amazon.com/Yubico-Y-159-YubiKey-4-Nano/dp/B018Y1XXT6/\", \"quantity\":" + 1 + " } ], \"shipping_address\" : {\"full_name\":\"Steven Smith\", \"street1\":\"11 Man Rd\", \"street2\":\"\", \"city\":\"Woonsocket\", \"state\":\"RI\", \"zip\":\"02844\", \"country\":\"US\", \"phone\":\"7746536483\" } } } ");
Mote: the values are different but I'm trying to achieve the same syntax.
System.out.println("Post String value: " + IOUtils.toString(postingString.getContent()));
httpPostRequest.addHeader("Authorization", "Token " + apiKey);
httpPostRequest.setEntity(postingString);
httpPostRequest.setHeader("Content-type", "application/json");
//httpPostRequest.addHeader("content-type", "application/x-www-form-urlencoded");
HttpResponse response = httpClient.execute(httpPostRequest);
System.out.println(response.toString());
The "postString" value is:
{"service" : {"type":"nnn", "discount":0.2,"items" : [ { "asin":"B018Y1XXT6", "link":"https://www.amazon.com/Yubico-Y-159-YubiKey-4-Nano/dp/B018Y1XXT6/", "quantity":1 } ], "shipping_address" : {"full_name":"Steven Smith", "street1":"11 Man Rd", "street2":"", "city":"Woonsocket", "state":"RI", "zip":"02844", "country":"US", "phone":"17746536483" } } }
However, when I attempt to submit the request I get a Bad Request error.
How can I format the String correctly?
Thanks
You have sent an incorrect json String if you want to go with the json provided .Following are the errors:
1) "service = {\"type\" should be {\"service\" : {\"type
2) discount should not be a string
\"discount\":\"0.2\", should be \"discount\":" + 0.2 + ",
3) items = [ should be \"items\" : [
4) quantity should not be string
\"quantity\":\"1\" } should be \"quantity\":" + 1 + "}
5) comma missing before shipping address key
] shipping_address = should be ], \"shipping_address\" :
6) add one more } at the end

Trying to parse JSON to String in Java

I'm trying to parse this stock info at:
http://www.google.com/finance/info?client=ig&q=csco
that's in JSON format to a map, essentially following this tutorial I saw using the quick-json jar but it keeps giving me an exception and I can't figure out why. Here's the code, any help is greatly appreciated
Tutorial link: https://code.google.com/p/quick-json/
public static void main(String args[]) throws IOException
{
String value="";
URL uri = new URL("http://www.google.com/finance/info?client=ig&q=csco");
BufferedReader input = new BufferedReader(new InputStreamReader(uri.openStream(), "UTF-8"));
while(input.readLine()!=null)
{
value+=input.readLine();
}
JsonParserFactory factory = JsonParserFactory.getInstance();
JSONParser parse = factory.newJsonParser();
Map jsonData =parse.parseJson(value);
System.out.println((String)jsonData.get("e"));
}
Here's the exception I get:
Exception in thread "main" com.json.exceptions.JSONParsingException: #Key-Heirarchy::root[0]/ #Key:: COMMA or ] is expected. but found :...#Position::5
at com.json.utils.JSONUtility.handleFailure(JSONUtility.java:124)
at com.json.parsers.JSONParser.stringLiteralTemplate(JSONParser.java:574)
at com.json.parsers.JSONParser.nonValidatingValueTemplate(JSONParser.java:698)
at com.json.parsers.JSONParser.jsonArrayTemplate(JSONParser.java:454)
at com.json.parsers.JSONParser.parseJson(JSONParser.java:170)
at parser.Scratch.main(Scratch.java:27)
EDIT: I also tried Map jsonData =parse.parseJson(value.substring(3) to start at [ but it still gives me an error
In addition to removing the leading // fix your loop as well. Change
while(input.readLine()!=null) // skipping odd lines
{
value+=input.readLine(); // reading even lines
}
to
String line = null;
while((line = input.readLine()) !=null)
{
value +=line;
}
or, better use a StringBuilder like
String line = null;
StringBuilder json = new StringBuilder();
while((line = input.readLine()) !=null)
{
json.append(line);
}
value = json.substring(3); // removes the leading "// "
EDIT:
I'm not familiar with your JSON parser. With the org.json. Java parser you could do it this way.
JSONArray jsonRoot = new JSONArray(value);
JSONObject quote = jsonRoot.get(0);
System.out.println ("e = " + quote.getString("e"));
But, as a workaround you could strip the [] from StringBuilder as
// removes the leading "// [" and trailing "]"
value = json.substring(4, json.length() - 1);
This json is not a valid, have two "//".
Use http://jsonlint.com/ to validate this
The response from that URL starts with //, which isn't valid JSON:
// [ { "id": "99624" ,"t" : "CSCO" ,"e" : "NASDAQ" ,"l" : "24.00" ,"l_cur" : "24.00" ,"s": "2" ,"ltt":"4:00PM EDT" ,"lt" : "Jun 25, 4:00PM EDT" ,"c" : "-0.05" ,"cp" : "-0.21" ,"ccol" : "chr" ,"el": "24.00" ,"el_cur": "24.00" ,"elt" : "Jun 25, 5:54PM EDT" ,"ec" : "0.00" ,"ecp" : "0.00" ,"eccol" : "chb" ,"div" : "0.17" ,"yld" : "2.83" } ]
According to this and this, the Google Finance API is deprecated anyway, so you may want to find something else.
Following blog has enough number of very good examples on quick-json parser
It has got other competitive parsers examples as well
http://codesnippets4all.com/html/parsers/json/quick-json.htm
Add this to your code:
String line = null;
while((line = input.readLine()) !=null)
{
value += line;
}
value = value.replace("// ", "");
You need to replace the // at the beginning to "clean" the JSON before you can parse it.
It seems you are using old quick-json parser version. Use the latest version for parsing
quick-json-1.0.2.3.jar
I could see that the json is coming as follows,
// [
{
"id": "99624"
,"t" : "CSCO"
,"e" : "NASDAQ"
,"l" : "25.41"
,"l_cur" : "25.41"
,"s": "2"
,"ltt":"3:59PM EDT"
,"lt" : "Jul 10, 3:59PM EDT"
,"c" : "+0.25"
,"cp" : "1.01"
,"ccol" : "chg"
,"el": "25.55"
,"el_cur": "25.55"
,"elt" : "Jul 10, 7:07PM EDT"
,"ec" : "+0.14"
,"ecp" : "0.55"
,"eccol" : "chg"
,"div" : "0.17"
,"yld" : "2.68"
}
]
This is not valid JSON, it should not be preceded by //
// [
remove // and just use from [ till end of the json string
i was able to parse successfully the below json string without //
[
{
"id": "99624"
,"t" : "CSCO"
,"e" : "NASDAQ"
,"l" : "25.41"
,"l_cur" : "25.41"
,"s": "2"
,"ltt":"3:59PM EDT"
,"lt" : "Jul 10, 3:59PM EDT"
,"c" : "+0.25"
,"cp" : "1.01"
,"ccol" : "chg"
,"el": "25.55"
,"el_cur": "25.55"
,"elt" : "Jul 10, 7:07PM EDT"
,"ec" : "+0.14"
,"ecp" : "0.55"
,"eccol" : "chg"
,"div" : "0.17"
,"yld" : "2.68"
}
]
Below is the output i've got with version quick-json-1.0.2.3.jar
{root=[{e=NASDAQ, c=+0.25, div=0.17, l=25.41, lt=Jul 10, 3:59PM EDT, ec=+0.14, ltt=3:59PM EDT, elt=Jul 10, 7:07PM EDT, id=99624, yld=2.68, el_cur=25.55, t=CSCO, cp=1.01, s=2, el=25.55, l_cur=25.41, eccol=chg, ccol=chg, ecp=0.55}]}

how can i loop through the returned JSON using Httpclient

I have the following code for calling an API that returns JSON with the following format:-
{
"data": [
{
" Ser": 1,
" No": 1
},
{
" Ser": 2,
" No": 2
},
{
" Ser": 3,
" No": 3
},
{
" Ser": 4,
" No": 4
},
{
" Ser": 5,
" No": 5
},
]
}
The code is:-
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet("/json/api/getinfo?type=100");
HttpResponse response = client.execute(request);
// Get the response, how i can loop through the returned JSON and assign the reterned json to a global parameters which i can access from ym system using has values #parameter1# , #parameter2#, etc.
so how can I loop through the returned JSON and assign it 'NO' to the global parameters?
Best Regards
You should get the content out of the HttpReponse object through the HttpEntity.getContent() as mentioned in the documentation. The content should then be fed to a JSONObject from any JSON library like the one from json.org/java. Then you can traverse the JSON output through the JSONObject and extract elements out of it.
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null)
{
//
// Using Commons IO library's IOUtils method
// to read the content from the stream.
//
String json = IOUtils.toString(entity.getContent());
JSONObject obj = new JSONObject(json);
// Process the JSON
// shutdown the connection.
}

Get latitude & longitude from given address name. NOT Geocoder

I have an address name and I want to get an accurate latitude & longitude for it. I know we can get this using Geocoder's getFromLocationName(address,maxresult).
The problem is, the result I get is always null - unlike the result that we get with https://maps.google.com/. This always allows me to get some results, unlike Geocoder.
I also tried another way: "http://maps.google.com/maps/api/geocode/json?address=" + address + "&sensor=false" (Here's a link!) It gives better results than geocoder, but often returns the error (java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer). It's boring.
My question is: How can we get the same latlong result we would get by searching on https://maps.google.com/ from within java code?
additional:where is the api document about using "http://maps.google.com/maps/api/geocode/json?address=" + address + "&sensor=false"
Albert, I think your concern is that you code is not working. Here goes, the code below works for me really well. I think you are missing URIUtil.encodeQuery to convert your string to a URI.
I am using gson library, download it and add it to your path.
To get the class's for your gson parsing, you need to goto jsonschema2pojo. Just fire http://maps.googleapis.com/maps/api/geocode/json?address=Sayaji+Hotel+Near+balewadi+stadium+pune&sensor=true on your browser, get the results and paste it on this site. It will generate your pojo's for you. You may need to also add a annotation.jar.
Trust me, it is easy to get working. Don't get frustrated yet.
try {
URL url = new URL(
"http://maps.googleapis.com/maps/api/geocode/json?address="
+ URIUtil.encodeQuery("Sayaji Hotel, Near balewadi stadium, pune") + "&sensor=true");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
String output = "", full = "";
while ((output = br.readLine()) != null) {
System.out.println(output);
full += output;
}
PincodeVerify gson = new Gson().fromJson(full, PincodeVerify.class);
response = new IsPincodeSupportedResponse(new PincodeVerifyConcrete(
gson.getResults().get(0).getFormatted_address(),
gson.getResults().get(0).getGeometry().getLocation().getLat(),
gson.getResults().get(0).getGeometry().getLocation().getLng())) ;
try {
String address = response.getAddress();
Double latitude = response.getLatitude(), longitude = response.getLongitude();
if (address == null || address.length() <= 0) {
log.error("Address is null");
}
} catch (NullPointerException e) {
log.error("Address, latitude on longitude is null");
}
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
The Geocode http works, I just fired it, results below
{
"results" : [
{
"address_components" : [
{
"long_name" : "Pune",
"short_name" : "Pune",
"types" : [ "locality", "political" ]
},
{
"long_name" : "Pune",
"short_name" : "Pune",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Maharashtra",
"short_name" : "MH",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "India",
"short_name" : "IN",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "Pune, Maharashtra, India",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 18.63469650,
"lng" : 73.98948670
},
"southwest" : {
"lat" : 18.41367390,
"lng" : 73.73989109999999
}
},
"location" : {
"lat" : 18.52043030,
"lng" : 73.85674370
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : 18.63469650,
"lng" : 73.98948670
},
"southwest" : {
"lat" : 18.41367390,
"lng" : 73.73989109999999
}
}
},
"types" : [ "locality", "political" ]
}
],
"status" : "OK"
}
Edit
On 'answers do not contain enough detail`
From all the research you are expecting that google map have a reference to every combination of locality, area, city. But the fact remains that google map contains geo and reverse-geo in its own context. You cannot expect it to have a combination like Sayaji Hotel, Near balewadi stadium, pune. Web google maps will locate it for you since it uses a more extensive Search rich google backend. The google api's only reverse geo address received from their own api's. To me it seems like a reasonable way to work, considering how complex our Indian address system is, 2nd cross road can be miles away from 1st Cross road :)
Hope this helps you:
public static GeoPoint getGeoPointFromAddress(String locationAddress) {
GeoPoint locationPoint = null;
String locationAddres = locationAddress.replaceAll(" ", "%20");
String str = "http://maps.googleapis.com/maps/api/geocode/json?address="
+ locationAddres + "&sensor=true";
String ss = readWebService(str);
JSONObject json;
try {
String lat, lon;
json = new JSONObject(ss);
JSONObject geoMetryObject = new JSONObject();
JSONObject locations = new JSONObject();
JSONArray jarr = json.getJSONArray("results");
int i;
for (i = 0; i < jarr.length(); i++) {
json = jarr.getJSONObject(i);
geoMetryObject = json.getJSONObject("geometry");
locations = geoMetryObject.getJSONObject("location");
lat = locations.getString("lat");
lon = locations.getString("lng");
locationPoint = Utils.getGeoPoint(Double.parseDouble(lat),
Double.parseDouble(lon));
}
} catch (Exception e) {
e.printStackTrace();
}
return locationPoint;
}
I use, in order:
- Google Geocoding API v3 (in few cases there's a problem described here)
- Geocoder (in some cases there's a problem described here).
If I don't receive results from Google Geocoding API I use the Geocoder.
As far as I noticed Google Maps is using the Google Places API for auto complete and then gets the Details for the Location from which you can get the coordinates.
https://developers.google.com/places/documentation/
https://developers.google.com/places/training/
This method should will give you the expected results.
String locationAddres = anyLocationSpec.replaceAll(" ", "%20");
URL url = new URL("https://maps.googleapis.com/maps/api/geocode/json?sensor=false&address="+locationAddres+"&language=en&key="YourKey");
try(InputStream is = url.openStream(); JsonReader rdr = Json.createReader(is)) {
JsonObject obj = rdr.readObject();
JsonArray results = obj.getJsonArray("results");
JsonObject geoMetryObject, locations;
for (JsonObject result : results.getValuesAs(JsonObject.class)) {
geoMetryObject=result.getJsonObject("geometry");
locations=geoMetryObject.getJsonObject("location");
log.info("Using Gerocode call - lat : lng value for "+ anyLocationSpec +" is - "+locations.get("lat")+" : "+locations.get("lng"));
latLng = locations.get("lat").toString() + "," +locations.get("lng").toString();
}
}

Categories

Resources