Getting Http status 400 in api 23 and below - android

I have to call one Rest API of GET request.
When I used emulator of API 24 it working fine. but same code on my phone i.e API 23 and API 18 it give 400 status i.e. bad request.
URL url = new URL(voids[0]);
Log.i("url", voids[0]);
//URL url = new URL(urlString);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.addRequestProperty("User-Agent", "REST");
System.setProperty("http.keepAlive", "false");
con.setRequestProperty("Accept", "*//*");
con.setConnectTimeout(10000);
con.setReadTimeout(10000);
con.setAllowUserInteraction(false);
con.setRequestMethod("GET");
responseCode = con.getResponseCode();
System.out.println("Sending get request : " + url);
System.out.println("Response code : " + responseCode);
// Reading response from input Stream
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String output;
StringBuffer response = new StringBuffer();
while ((output = in.readLine()) != null) {
response.append(output);
}
in.close();
System.out.println(response.toString());
Url : http://milk.gall5.com/api/SalePunch?CustomerID=1&Model={"CustomerID":"1","lstSalesPunchDetail":[{"ListManufacturer":[{"ManufactureID":1,"ManufacturerName":"Amul","One":40,"OneByFour":10,"OneByTwo":20,"QtyOne":0,"QtyOneByFour":23,"QtyOneByTwo":330,"visibilityOne":true,"visibilityOneByFour":true,"visibilityOneByTwo":true}],"ProductId":2,"ProductName":"Ton Milk"}]}

Try to encode the Model parameter of your URL first.
You can do that with the URLEncoder.encode() method

Related

Android HttpClient response

I'm trying to send json data to a php script from my Android application with HttpClient, and get the response.
Android Code
private void sendPurchase(String SKU) throws IOException{
Log.e("sendPurchase","Inside sendPurchase");
final SharedPreferences prefs = getGCMPreferences(getApplicationContext());
int pur_user = prefs.getInt("C_user", Integer.MIN_VALUE);
InputStream inputStream = null;
String result = "";
HttpClient httpclient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("http://www.*.com/includes/purchase.php");
JSONObject json = new JSONObject();
try {
json.put("PUR_sku", SKU);
json.put("PUR_user", pur_user);
} catch (JSONException e) { Log.e("SendPurchase","Problem with Json Object"); }
Log.i("JSONObject", json.toString());
StringEntity se = new StringEntity(json.toString(), HTTP.UTF_8);
httpPost.setEntity(se);
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
HttpResponse httpResponse = httpclient.execute(httpPost);
inputStream = httpResponse.getEntity().getContent();
if(inputStream != null){ result = convertInputStreamToString(inputStream); }
else{result = "Did not work!"; }
Log.e("RESULT",result);
}
private static String convertInputStreamToString(InputStream inputStream) throws IOException{
BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(inputStream));
String line = "";
String result = "";
while((line = bufferedReader.readLine()) != null)
result += line;
inputStream.close();
return result;
}
And the PHP script
<?
$auth=0;
require('./connexion.php');
$data = file_get_contents('php://input');
//$data = '{"PUR_sku":"singleone","PUR_user":"3"}';
$json = json_decode($data,true);
/* Some database stuff ... */
echo "Retour ".print_r($json)." et ".$json['PUR_sku']." et ".$json['PUR_user'];
?>
When i launch the app and execute sendPurchase function, it seems to be ok until the execution of the HttpPost. In the logcat i get all the logs with correct params, except the last log "RESULT" that does not appear.
That's why i guess something is going wrong with the HttpPost execution, but actually i don't know if the problem comes from the application side or the php script side...
When i execute the php script alone in a web browser, replacing first $data line by the second one, everything is ok. But when it comes from the application it's not ok...
The Json Object sent (i hope) to the script seems ok too : {"PUR_user":3,"PUR_sku":"singleone"}
(the sendPurchase function is executed in Background).
Any idea about what i'm doing wrong ? Thanks !
/EDIT/
Here is the logcat for #RyuZz solution.
My code is about purchasing an item, consume it and send new value to my database on a web server. The purchase & consume are ok, but i can't send the values to the web server.
And again, when i execute the php script alone in a web browser, replacing first $data line by the second one, everything is ok.
Note that i have another similar code to register user to GCM, using HttpClient, and that code works fine.
06-25 14:07:12.968: D/IabHelper(21833): Successfully consumed sku: singleconf
06-25 14:07:12.968: D/IabHelper(21833): Ending async operation: consume
06-25 14:07:12.979: D/CONSUME(21833): Consumption finished. Purchase: PurchaseInfo(type:inapp):{"orderId":"12999763169054705758.1353445524837889","packageName":"com.*.*","productId":"singleconf","purchaseTime":1435234296875,"purchaseState":0,"purchaseToken":"bohbcbiigcbidfficbikebnk.AO-J1OzuQ_SsNTG1h9MtUvbaPc3PeN9nBHG-qBOE82ao1rTDFNrgA7tYQcMdECxCVFrrZEn_QifQ28OcIupyesZI-5cjDILFODYpBEaeqMfE0wCAeMFkJLfNUK_TsKPMj7F2sBDdgOYx"}, result: IabResult: Successful consume of sku singleconf (response: 0:OK)
06-25 14:07:12.979: D/CONSUME(21833): You bought & consumed a single conf
06-25 14:07:12.979: D/CONSUME(21833): End consumption flow.
06-25 14:07:12.979: E/Purchase Background(21833): Inside doInBackground
06-25 14:07:12.979: E/sendPurchase(21833): Failed to send HTTP POST request due to: java.lang.NullPointerException
You can try the following instead of HttpClient which is anyway deprecated:
try{
int pur_user = prefs.getInt("C_user", Integer.MIN_VALUE);
URL url = new URL("http://www.*.com/includes/purchase.php");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Accept", "application/json");
connection.setRequestMethod("POST");
JSONObject jsonObject = new JSONObject();
jsonObject.put("PUR_sku", SKU);
jsonObject.put("PUR_user", pur_user);
//convert JSONObject to JSON to String
json = jsonObject.toString();
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
writer.write(json);
writer.close();
responseCode = connection.getResponseCode();
if(responseCode == 200) {
InputStream content = connection.getInputStream();
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(content, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null)
{
sb.append(line).append("\n");
}
result = sb.toString();
//TODO get your stuff from result
content.close();
} catch (Exception ex) {
Log.e(TAG, "Failed to parse JSON due to: " + ex);
} finally {
connection.disconnect();
}
} else {
Log.e(TAG, "Server responded with status code: " + responseCode);
}
} catch(Exception ex) {
Log.e(TAG, "Failed to send HTTP POST request due to: " + ex);
}
if this isn't working, please post the logcat.
Don't forget to implement the required permissions in your manifest:
<uses-permission
android:name="android.permission.INTERNET" />

Error on using googmaps api

Im getting the following error on trying to use an web service from google api maps:
{
"error_message" : "Requests to this API must be over SSL.",
"results" : [],
"status" : "REQUEST_DENIED"
}
the url used to invoke the web service:
http://maps.googleapis.com/maps/api/geocode/json?key=my_key=Rua+Vergueiro,+1883,+S%C3%A3o+Paulo,+Brazil&sensor=true
method used to call the web service:
enter code here
public static String httpPost(String urlStr) throws Exception {
String novaUrl = urlStr.trim();
novaUrl = urlStr.replaceAll(" ", "+");
novaUrl = novaUrl.replaceAll("\r", "");
novaUrl = novaUrl.replaceAll("\t", "");
novaUrl = novaUrl.replaceAll("\n", "");
URL url = new URL(novaUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setAllowUserInteraction(false);
conn.setRequestProperty("Content-Type", "application/x-www-form-urldecoded");
// Create the form content
OutputStream out = conn.getOutputStream();
Writer writer = new OutputStreamWriter(out, "UTF-8");
writer.close();
out.close();
// Buffer the result into a string
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = rd.readLine()) != null) {
sb.append(line);
}
rd.close();
conn.disconnect();
Spanned retorno = Html.fromHtml(sb.toString());
return retorno.toString();
}
How to solve this problem?
Thanks.
Try using this URL. Error just because of http and https. https is used for secure line.
https://maps.googleapis.com/maps/api/geocode/json?key=my_key=Rua+Vergueiro,+1883,+S%C3%A3o+Paulo,+Brazil&sensor=true
Now when you click on this you will get some error like this .. The provided API key is invalid.
For that just provide correct API key that you retrieved from Google Console.
Your given URL :: https://maps.googleapis.com/maps/api/geocode/json?key=my_key=Rua+Vergueiro,+1883,+S%C3%A3o+Paulo,+Brazil&sensor=true
here key=my_key Here is the problem, please provide correct API key and you problem will be solved.

POST function for REST service returns empty response

I'm trying to do a post method for a REST service, but I'm not getting any response from server:
public JSONObject postValues (String strUrl, String strJsonArray) throws Exception{
JSONObject jsonObject = null;
URL url = new URL(strUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
strJsonArray = "data=" + strJsonArray;
Log.e("result",""+strJsonArray);
OutputStream os = conn.getOutputStream();
os.write(strJsonArray.getBytes());
os.flush();
conn.connect();
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
String output;
StringBuilder sb = new StringBuilder();
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
Log.e("output",output);
sb.append(output);
}
Log.e("output",sb.toString());
jsonObject = new JSONObject(sb.toString());
conn.disconnect();
return jsonObject;
}
When I see my logCat a get:
output {}
I know that the server is working right because I'm using the "advanced REST client" plugin of google chrome. If I call the URL manually (using the plugin of course)I get the desired answer:
{"message":"OK","code":200}
But if I try to use my function, my strJsonArray is inserted but I get an empty respond from server.
Is there anything wrong with my code?.
Everything looks good...
You could use Wireshark to capture the packets sent to and received from the server using an emulator and the chrome rest client. Then you can compare them and maybe find out what's wrong.
You could also check if theres something in the error stream (conn.getErrorStream()).

Android - Login HTTP works API 10 Only

To get some information, my app emulates the behaviour of a web browser. The log-in session of the target website has 3 steps:
Access the form (gives a cookie for authentication)
Send a POST request with all information
The server answers contains a link in the headers that indicates the address to go to
I have three functions for that, one that gets the page and extracts the session Cookie.
The second one extracts the form of this first page and puts the right infos.
The third one prepares the POST request, sends it, and read the Location in the headers.
It works fine... But with API 10 only.......
Does anyone know what has changed after API 10??
I've tried on Emulators with API 13 or more, and at the moment of sending the POST request, the server answers as if the Cookie given in the first page is not valid. (I get an answer Code of 200, and the login page... Instead of a 302 answer and the Location to follow).
I use the java.net CookieManager & CookieHandler
Here is the first function for example:
private String GetPageContent(String url) throws Exception {
URL obj = new URL(url);
conn = (HttpURLConnection) obj.openConnection();
// default is GET
conn.setRequestMethod("GET");
conn.setUseCaches(false);
// act like a browser
conn.setRequestProperty("User-Agent", USER_AGENT);
conn.setRequestProperty("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
conn.setRequestProperty("Accept-Language", "fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4");
conn.setRequestProperty("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.3");
if (MainActivity.cookies != null) {
for (String cookie : MainActivity.cookies) {
conn.setRequestProperty("Cookie", cookie);
}
}
int responseCode = conn.getResponseCode();
System.out.println("\nSending 'GET' request to URL : " + url);
System.out.println("Response Code : " + responseCode);
BufferedReader in =
new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// Get the response cookies
setCookies(conn.getHeaderFields().get("Set-Cookie"));
return response.toString();
}
And this is the third function (nothing special in the second one:
private void sendPost(String url, String postParams) throws Exception {
URL obj = new URL(url);
conn = (HttpURLConnection) obj.openConnection();
// Acts like a browser
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("User-Agent", USER_AGENT);
conn.setRequestProperty("Accept",
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
conn.setRequestProperty("Accept-Language", "fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4");
for (String cookie : MainActivity.cookies) {
System.out.println("Adding Cookie: "+cookie);
conn.addRequestProperty("Cookie", cookie.split(";", 1)[0]);
}
conn.setRequestProperty("Connection", "keep-alive");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", Integer.toString(postParams.length()));
// Update Progress bar -> 25
mProgression += 5;
msg = mHandler.obtainMessage(PROGRESSION, mProgression, 0);
mHandler.sendMessage(msg);
conn.setDoOutput(true);
conn.setDoInput(true);
// Send post request
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
wr.writeBytes(postParams);
wr.flush();
wr.close();
int responseCode = conn.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + postParams);
System.out.println("Response Code : " + responseCode);
System.out.println("Attempt to get location");
// Get the location of the ticket in the ResponseHeader
setLocation(conn.getHeaderFields().get("Location"));
// Get the Cookie of the ResponseHeader AFTER sending credentials
setLoginCookies(conn.getHeaderFields().get("Set-Cookie"));
BufferedReader in =
new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// System.out.println(response.toString());
}
There is no problem with the log cat, the third function can't go past the "get("Location")" since the server doesn't return any location...
Thanks to whoever takes time to answer that one...
Btw, it's my first app :)
Thanks again!
I think you should use a better client that will handle all the headers and the body by itself, you can use android built in HTTP client but it can not persist cookies, or you can use loopj async client that works great.
Actually I published a post that explained how we did it, you can read it here.

Basic authentication to access assembla rest apis from android

I want to use assembla apis from android environment for my project.
I am trying to do basic authentication as follow :
String authentication = "username:password";
String encoding = Base64.encodeToString(authentication.getBytes(), 0);
URL url = new URL("https://www.assembla.com/");
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Authorization", "Basic " + encoding);
conn.setDoOutput(true);
conn.connect();
System.out.println(conn.getResponseCode());
System.out.println(conn.getResponseMessage());
I am getting 400 and Bad Request in output.
is there something wrong with URL that i am using or some other thing is going wrong?
It looks like the question was answered here. You need to use Base64.NO_WRAP flag when encoding username-password pair:
String encoding = Base64.encodeToString(authentication.getBytes(), Base64.NO_WRAP);
By default the Android Base64 util adds a newline character to the end of the encoded string. This invalidates the HTTP headers and causes the "Bad request".
The Base64.NO_WRAP flag tells the util to create the encoded string without the newline character thus keeping the HTTP headers intact.
REST API with HTTP Authentication Output:- I got the result
String authentication = "username:password";
String encoding = Base64.encodeToString(authentication.getBytes(), Base64.NO_WRAP);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setDoOutput(true);
conn.setRequestProperty ("Authorization", "Basic " + encoding);
conn.connect();
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write( data );
wr.flush();
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
while((line = reader.readLine()) != null)
{
// Append server response in string
sb.append(line + "\n");
}
Content = sb.toString();

Categories

Resources