I have a link that is way too long (got some URL-paramameters etc). I want to shorten this using the googpe API urlshortener.
The API-key is created in google Developers Console. The key is an 'public API access' and a 'Key for server applications'.
Can anyone see why this code does not work? I have tried for way too long to make this happen.
try {
String g = "https://www.googleapis.com/urlshortener/v1/url";
String url = g + "?key=secretKey";
HttpClient client = HttpClientBuilder.create().build();
HttpPost post = new HttpPost(url);
// add header
//post.setHeader("User-Agent", USER_AGENT);
post.setHeader("Accept", "application/json");
//add the long url as a parameter
List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
urlParameters.add(new BasicNameValuePair("longUrl", "www.google.com"));
post.setEntity(new UrlEncodedFormEntity(urlParameters));
HttpResponse response = client.execute(post);
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);
} } catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Returns a responsecode of 400
I guess there was just a problem with my HTTP-request. When I used the code used here: http://www.snip2code.com/Snippet/216067/Call-Google-Shorten-URL-API it worked.
Posting this answer instead of just deleting the question, because the API is recently changed (I guess mid-2014), so there is not much updated examples of this.
Good luck to all of you trying to access this API :)
I am developing a web app in JSP. For same project I'm developing an Android app. The web app uses Apache Tomcat and MySQL. Now I want to log in from the Android application by retrieving data from MySQL database. But how?
I did find many tutorials but all are using PHP scripts. I'm using Eclipse for both apps.
For android Try this.
private static HttpClient getHttpClient() {
if (mHttpClient == null) {
mHttpClient = new DefaultHttpClient();
final HttpParams params = mHttpClient.getParams();
HttpConnectionParams.setConnectionTimeout(params, HTTP_TIMEOUT);
HttpConnectionParams.setSoTimeout(params, HTTP_TIMEOUT);
ConnManagerParams.setTimeout(params, HTTP_TIMEOUT);
}
return mHttpClient;
}
And then
public static String sendFirst(String requestString) throws Exception {
BufferedReader in = null;
try {
HttpClient client = getHttpClient();
HttpPost request = new HttpPost(universal_URL_MENU+"?request_menu="+start_menu);
HttpResponse response = client.execute(request);
System.out.println("response in class"+response);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
result = sb.toString();
// }
}catch(Exception e){
e.printStackTrace();
System.out.println("catch");
}
finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}
Where
public static String universal_URL_MENU = "http://192.***.1.#:9999/my_Project/ReqFromTabFor.do";
Now for Jsp or Servlet
try{
PrintWriter out=res.getWriter();
String subcategory=req.getParameter("request_menu");
System.out.println("Receive : "+subcategory);
JSONObject jobj=UserDelegate.reqFromTabForMenuBySCatg(subcategory);
}
if(jobj!=null){
out.println(jobj);
}else{
out.print("Sorry Not Available");
}
}catch(Exception e){ e.printStackTrace(); }
What happens between the client (your Android app) and the server is loosely coupled, meaning that they are not related whatsoever except for the protocol with which they communicate, which for a web service is HTTP.
Usually a client (either an app or a web browser) makes an HTTP request sending parameters (e.g. login, password) with POST or GET methods. The server takes these parameters and processes them according to its needs.
This may sound obvious, but you say that all the tutorials are using php script, so you seem confused: your problem on Android? or is your problem in the server?
The code you need in your Android app is EXACTLY THE SAME regardless of the server technology (asp, cgi, jsp, php...) and database (MySql, Oracle...), because the HTTP protocol is standard.
Here is an example I copied from here to make a simple HTTP request with two POST parameters.
public void postData() {
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.yoursite.com/script.php");
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("id", "12345"));
nameValuePairs.add(new BasicNameValuePair("stringdata", "AndDev is Cool!"));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
}
I need to make about 15 calls to diferent web services (php) at the application startup.
I'm using the following code for the post
public static String post(String url, List<BasicNameValuePair>
postvalues, HttpClient httpclient) {
try {
if (httpclient == null) {
httpclient = new DefaultHttpClient();
}
HttpPost httppost = new HttpPost(url);
if ((postvalues == null)) {
postvalues = new ArrayList<BasicNameValuePair>();
}
httppost.setEntity(new UrlEncodedFormEntity(postvalues, "UTF-8"));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
return requestToString(response);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private static String requestToString(HttpResponse response) {
String result = "";
try {
InputStream in = response.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder str = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
str.append(line + "\n");
}
in.close();
result = str.toString();
} catch (Exception ex) {
result = "Error";
}
return result;
}
The problem is that some of the petitions must be requested in a given order and each request takes about 1-2 second so the "Loading splash" takes about 10 seconds.
So my question is:Since all the connections are to the same server, how can I improve this delay? Is there some way of open a connection and send all the petitions through that "tunnel" reducing the delay?
NOTE: I tested the code and the requests take the same time reusing the httpclient using a new one in each connection
Thanks
What you have in mind is a HTTP persistent connection which reuses the TCP connection.
About this topic there is already a good question & answer here on Stackoverflow:
Persistent HttpURLConnections on Android
I've written some code for my Android device to login to a web site over HTTPS and parse some data out of the resulting pages. An HttpGet happens first to get some info needed for login, then an HttpPost to do the actual login process.
The code below works great in a Java project within Eclipse which has the following JAR files on the build path: httpcore-4.1-beta2.jar, httpclient-4.1-alpha2.jar, httpmime-4.1-alpha2.jar, and commons-logging-1.1.1.jar.
public static MyBean gatherData(String username, String password) {
MyBean myBean = new MyBean();
try {
HttpResponse response = doHttpGet(URL_PAGE_LOGIN, null, null);
System.out.println("Got login page");
String content = EntityUtils.toString(response.getEntity());
String token = ContentParser.getToken(content);
String cookie = getCookie(response);
System.out.println("Performing login");
System.out.println("token = "+token +" || cookie = "+cookie);
response = doLoginPost(username,password,cookie, token);
int respCode = response.getStatusLine().getStatusCode();
if (respCode != 302) {
System.out.println("ERROR: not a 302 redirect!: code is \""+ respCode+"\"");
if (respCode == 200) {
System.out.println(getHeaders(response));
System.out.println(EntityUtils.toString(response.getEntity()).substring(0, 500));
}
} else {
System.out.println("Logged in OK, loading account home");
// redirect handler and rest of parse removed
}
}catch (Exception e) {
System.out.println("ERROR in gatherdata: "+e.toString());
e.printStackTrace();
}
return myBean;
}
private static HttpResponse doHttpGet(String url, String cookie, String referrer) {
try {
HttpClient client = new DefaultHttpClient();
client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
client.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, "UTF-8");
HttpGet httpGet = new HttpGet(url);
httpGet.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
httpGet.setHeader(HEADER_USER_AGENT,HEADER_USER_AGENT_VALUE);
if (referrer != null && !referrer.equals("")) httpGet.setHeader(HEADER_REFERER,referrer);
if (cookie != null && !cookie.equals("")) httpGet.setHeader(HEADER_COOKIE,cookie);
return client.execute(httpGet);
} catch (Exception e) {
e.printStackTrace();
throw new ConnectException("Failed to read content from response");
}
}
private static HttpResponse doLoginPost(String username, String password, String cookie, String token) throws ClientProtocolException, IOException {
try {
HttpClient client = new DefaultHttpClient();
client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
client.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, "UTF-8");
HttpPost post = new HttpPost(URL_LOGIN_SUBMIT);
post.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
post.setHeader(HEADER_USER_AGENT,HEADER_USER_AGENT_VALUE);
post.setHeader(HEADER_REFERER, URL_PAGE_LOGIN);
post.setHeader(HEADER_COOKIE, cookie);
post.setHeader("Content-Type","application/x-www-form-urlencoded");
List<NameValuePair> formParams = new ArrayList<NameValuePair>();
formParams.add(new BasicNameValuePair("org.apache.struts.taglib.html.TOKEN", token));
formParams.add(new BasicNameValuePair("showLogin", "true"));
formParams.add(new BasicNameValuePair("upgrade", ""));
formParams.add(new BasicNameValuePair("username", username));
formParams.add(new BasicNameValuePair("password", password));
formParams.add(new BasicNameValuePair("submit", "Secure+Log+in"));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams,HTTP.UTF_8);
post.setEntity(entity);
return client.execute(post);
} catch (Exception e) {
e.printStackTrace();
throw new ConnectException("ERROR in doLoginPost(): "+e.getMessage());
}
}
The server (which is not under my control) returns a 302 redirect when the login was successful, and 200 if it fails and re-loads the login page. When run with the above JAR files I get the 302 redirect, however if I run the exact same code from an Android project with the 1.6 Android JAR file on the build path I get the 200 response from the server. I get the same 200 response when running the code on my 2.2 device.
My android application has internet permissions, and the HttpGet works fine. I'm assuming that the problem lies in the fact that HttpPost (or some other class) is different in some significant way between the Android JAR version and the newer Apache versions.
I've tried adding the Apache libraries to the build path of the Android project, but due to the duplicate classes I get messages like: INFO/dalvikvm(390): DexOpt: not resolving ambiguous class 'Lorg/apache/http/impl/client/DefaultHttpClient;' in the log. I've also tried using a MultipartEntity instead of the UrlEncodedFormEntity but I get the same 200 result.
So, I have a few questions:
Can I force the code running under Android to use the newer Apache libraries in preference to the Android versions?
If not, does anyone have any ideas how can I alter my code so that it works with the Android JAR file?
Are there any other, totally different approaches to doing an HttpPost in Android?
Any other ideas?
I've read a lot of posts and code, but I'm not getting anywhere.
I have now given up on getting the HttpClient route to give the expected response from the server when run on Android. Instead I rewrote the doPost method above to use an HttpsURLConnection instead. Here's the new (working) version in the hope that it's useful to someone.
private static LoginBean altPost(String username, String password, String cookie, String token){
LoginBean loginBean = new LoginBean();
HttpsURLConnection urlc = null;
OutputStreamWriter out = null;
DataOutputStream dataout = null;
BufferedReader in = null;
try {
URL url = new URL(URL_LOGIN_SUBMIT);
urlc = (HttpsURLConnection) url.openConnection();
urlc.setRequestMethod("POST");
urlc.setDoOutput(true);
urlc.setDoInput(true);
urlc.setUseCaches(false);
urlc.setAllowUserInteraction(false);
urlc.setRequestProperty(HEADER_USER_AGENT, HEADER_USER_AGENT_VALUE_FF);
urlc.setRequestProperty("Cookie", cookie);
urlc.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
String output = "org.apache.struts.taglib.html.TOKEN="+ URLEncoder.encode(token, HTTP.UTF_8)
+"&showLogin=true&upgrade=&username="+ URLEncoder.encode(username, HTTP.UTF_8)
+"&password="+ URLEncoder.encode(password, HTTP.UTF_8)+"&submit="
+URLEncoder.encode("Secure+Log+in", HTTP.UTF_8);
dataout = new DataOutputStream(urlc.getOutputStream());
// perform POST operation
dataout.writeBytes(output);
// get response info
loginBean.setResponseCode(urlc.getResponseCode());
// get required headers
String headerName = null;
StringBuffer newCookie = new StringBuffer(100);
String redirectLocation = "";
for (int i=1; (headerName = urlc.getHeaderField(i)) != null;i++) {
if (headerName.indexOf(COOKIE_VALUE_SESSION) > -1) {
if (newCookie.length() > 0) {newCookie.append("; ");}
newCookie.append(headerName);
}
if (headerName.indexOf(COOKIE_VALUE_AUTH) > -1) {
if (newCookie.length() > 0) {newCookie.append("; ");}
newCookie.append(headerName);
}
if (headerName.indexOf("https://") > -1) {
redirectLocation = headerName;
}
}
loginBean.setCookie(newCookie.toString());
loginBean.setRedirectUrl(redirectLocation);
in = new BufferedReader(new InputStreamReader(urlc.getInputStream()),8096);
String response;
// write html to System.out for debug
while ((response = in.readLine()) != null) {
System.out.println(response);
}
in.close();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return loginBean;
}
I still have no idea why the HttpClient way didn't work properly.
To avoid the collisions, use this JAR file for httpclient:
httplib
And this post would also be very useful:
An answer to Stack Overflow question Apache HTTP client or URLConnection
Is it possible that this website does user-agent detection and actually returns different results because it's Android? Given that 200 implies success, why must it give a 302 instead of a 200? Have you printed out the result that you get when it returns a 200, and does it give any additional information?
Check the RedirectHandler, override the default one and do some logging in it, I had problems with that when going to Android...
I have get a correct login using HttpRequest to work. It prints the correct html form of the logn page in my toast (just for testing). Now I want to set a cookie from that request. How is this possible?
If it necessary I can provide some code.
I already know about the CookieManager class, but how can I successfully do it?
Thanks in advance!
My code:
public String getPostRequest(String url, String user, String pass) {
HttpClient postClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse response;
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("login", user));
nameValuePairs.add(new BasicNameValuePair("pass", pass));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, HTTP.UTF_8));
response = postClient.execute(httpPost);
if(response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
String result = convertStreamToString(instream);
instream.close();
return result;
}
}
} catch (Exception e) {}
Toast.makeText(getApplicationContext(),
"Connection failed",
Toast.LENGTH_SHORT).show();
return null;
}
private String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
Well, this is pretty much it. convertStreamToString() function converts the InputStream into a String (plain HTML code), which I "toast" out to just test it (so it work), so the code is working though. Now to set the cookie. :-)
This is what I've reached for now:
// inside my if (entity != null) statement
List<Cookie> cookies = postClient.getCookieStore().getCookies();
String result = cookies.get(1).toString();
return result;
When I have logged in, the CookieList id 1 contains a value, otherwise the value is standard. So for now I know the difference in value, but how can I continue?
I think Android ships with Apache HttpClient 4.0.
You can check Chapter 3. HTTP state management topic from HttpClient Tutorial.
You can also refer similar questions on SO:
Android project using httpclient --> http.client (apache), post/get method
How do I manage cookies with HttpClient in Android and/or Java?
Also Check this example for usage: http://svn.apache.org/repos/asf/httpcomponents/httpclient/branches/4.0.x/httpclient/src/examples/org/apache/http/examples/client/ClientFormLogin.java