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();
Related
I have prepared one API, and I want to send one specific data with json posting.
My code works fine during working with Fiddler or site side.
But the problem is why some character didn't send, when we use Android version as a client device.
For example:
string a="mn✈" // correct on any device (android,site,Fiddler,...)
string b="mn✉" //correct on any device except(android) //getting 500 reponse
String requestURL = Utils.SERVER_URL + "PostJsonFeatures";
HttpURLConnection conn = (HttpURLConnection) new URL(requestURL).openConnection();
conn.setReadTimeout(15000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/json");
JSONObject postDataParams = new JSONObject();
postDataParams.put("Features", getAttributes());
postDataParams.put("productId", productId);
postDataParams.put("groupId", catId);
postDataParams.put("brandId", PrefManager.getInstance(context).getCompanyId());
postDataParams.put("languageId", PrefManager.getInstance(context).getLanguageApi());
DataOutputStream printout = new DataOutputStream(conn.getOutputStream ());
printout.write(postDataParams.toString().getBytes());
printout.flush ();
printout.close ();
You can decode to string and pass in url.
String parseString = URLDecoder.decode(URLEncoder.encode(myString, "UTF-8"), "ISO-8859-1");
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.
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()).
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.
I have an app I am developing that requires me to post data to a 3rd party API. I have been struggling with authentication since the beginning and kept putting off further and further, and now I'm stuck.
I have tried using an Authenticator, but have read all about how there appears to be a bug in certain Android versions: Authentication Example
I have tried several different options, including the Apache Commons HTTP Library with no success. After all of this, I decided to make sure that the API wasn't the pain point. So I wrote a quick WinForms program to test the API, which worked perfectly on the first try. So, the idea that I'm working from and the API I working with both seem fine, but I am in desperate need of some guidance as to why the Java code isn't working.
Examples follow:
C# Code that works everytime:
System.Net.ServicePointManager.Expect100Continue = false;
// Create a request using a URL that can receive a post.
WebRequest request = WebRequest.Create(addWorkoutUrl);
// Set the Method property of the request to POST.
request.Method = "POST";
// Create POST data and convert it to a byte array.
string postData = "distance=4000&hours=0&minutes=20&seconds=0&tenths=0&month=08&day=01&year=2011&typeOfWorkout=standard&weightClass=H&age=28";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Set the ContentType property of the WebRequest.
request.Headers["X-API-KEY"] = apiKey;
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes("username:password"));
request.ContentType = "application/x-www-form-urlencoded";
// Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length;
// Get the request stream.
Stream dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
// Get the response.
WebResponse response = request.GetResponse();
// Display the status.
MessageBox.Show(((HttpWebResponse)response).StatusDescription);
// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
// Display the content.
MessageBox.Show(responseFromServer);
// Clean up the streams.
reader.Close();
dataStream.Close();
response.Close();
Java code for Android that currently returns a 500:Internal Server Error, though I believe this is my fault.
URL url;
String data = "distance=4000&hours=0&minutes=20&seconds=0&tenths=0&month=08&day=01&year=2011&typeOfWorkout=standard&weightClass=H&age=28";
HttpURLConnection connection = null;
//Create connection
url = new URL(urlBasePath);
connection = (HttpURLConnection)url.openConnection();
connection.setConnectTimeout(10000);
connection.setUseCaches(false);
connection.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
connection.setRequestProperty("Accept","*/*");
connection.setRequestProperty("X-API-KEY", apiKey);
connection.setRequestProperty("Authorization", "Basic " +
Base64.encode((username + ":" + password).getBytes("UTF-8"), Base64.DEFAULT));
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length", "" + Integer.toString(data.getBytes("UTF-8").length));
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.write(data.getBytes("UTF-8"));
wr.flush();
wr.close();
statusCode = connection.getResponseCode();
statusReason = connection.getResponseMessage();
//At this point, I have the 500 error...
I figured out the problem, and the solution finally after stumbling across the root cause as mentioned in the comment above.
I was using Base64.encode() in my example, but I needed to be using Base64.encodeToString().
The difference being that encode() returns a byte[] and encodeToString() returns the string I was expecting.
Hopefully this will help somebody else who is caught by this.
Here's a nicer method to do to the POST.
install-package HttpClient
Then:
public void DoPost()
{
var httpClient = new HttpClient();
var creds = string.Format("{0}:{1}", _username, _password);
var basicAuth = string.Format("Basic {0}", Convert.ToBase64String(Encoding.UTF8.GetBytes(creds)));
httpClient.DefaultRequestHeaders.Add("Authorization", basicAuth);
var post = httpClient.PostAsync(_url,
new FormUrlEncodedContent(new Dictionary<string, string>
{
{ "name", "Henrik" },
{ "age", "99" }
}));
post.Wait();
}
I have tried this in java
import java.io.*;
import java.net.*;
class download{
public static void main(String args[]){
try{
String details = "API-Key=e6d871be90a689&orderInfo={\"booking\":{\"restaurantinfo\":{\"id\":\"5722\"},\"referrer\":{\"id\": \"9448476530\" }, \"bookingdetails\":{\"instructions\":\"Make the stuff spicy\",\"bookingtime\": \"2011-11-09 12:12 pm\", \"num_guests\": \"5\"}, \"customerinfo\":{\"name\":\"Ramjee Ganti\", \"mobile\":\"9345245530\", \"email\": \"sajid#pappilon.in\", \"landline\":{ \"number\":\"0908998393\",\"ext\":\"456\"}}}}";
Authenticator.setDefault(new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("admin", "1234".toCharArray());
}
});
HttpURLConnection conn = null;
//URL url = new URL("http://api-justeat.in/ma/orders/index");
URL url = new URL("http://api.geanly.in/ma/order_ma/index");
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput (true);
conn.setRequestMethod("POST");
//conn.setRequestMethod(HttpConnection.POST);
DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());
outStream.writeBytes(details);
outStream.flush();
outStream.close();
//Get Response
InputStream is = conn.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while((line = rd.readLine()) != null) {
System.out.println(line);
}
rd.close();
System.out.println(conn.getResponseCode() + "\n\n");
}catch(Exception e){
System.out.println(e);
}
}
}
this could help.