Java tutorial
package fi.iki.murgo.irssinotifier; import java.io.IOException; import java.util.*; import java.util.Map.Entry; import android.accounts.Account; import android.accounts.AuthenticatorException; import android.accounts.OperationCanceledException; import android.app.Activity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.params.ClientPNames; import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.cookie.Cookie; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.cookie.BasicClientCookie2; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import android.util.Log; public class Server { private static final String TAG = Server.class.getName(); private final Preferences preferences; private final Activity activity; private boolean usingDevServer = false; // must be false when deploying public enum ServerTarget { SaveSettings, Test, FetchData, Authenticate, Message, WipeSettings, GetNonce, License, } private Map<ServerTarget, String> serverUrls = new HashMap<ServerTarget, String>(); private DefaultHttpClient http_client = new DefaultHttpClient(); private static final int maxRetryCount = 2; public Server(Activity activity) { this.activity = activity; this.preferences = new Preferences(activity); String baseServerUrl = "https://irssinotifier.appspot.com"; if (usingDevServer) { baseServerUrl = "http://10.0.2.2:8080"; } serverUrls.put(ServerTarget.SaveSettings, baseServerUrl + "/API/Settings"); serverUrls.put(ServerTarget.WipeSettings, baseServerUrl + "/API/Wipe"); serverUrls.put(ServerTarget.Message, baseServerUrl + "/API/Message"); serverUrls.put(ServerTarget.Authenticate, baseServerUrl + "/_ah/login?continue=https://localhost/&auth="); serverUrls.put(ServerTarget.GetNonce, baseServerUrl + "/API/Nonce"); serverUrls.put(ServerTarget.License, baseServerUrl + "/API/License"); } public boolean authenticate() throws IOException { return authenticate(0); } private boolean authenticate(int retryCount) throws IOException { if (usingDevServer) { BasicClientCookie2 cookie = new BasicClientCookie2("dev_appserver_login", "irssinotifier@gmail.com:False:118887942201532232498"); cookie.setDomain("10.0.2.2"); cookie.setPath("/"); http_client.getCookieStore().addCookie(cookie); return true; } String token = preferences.getAuthToken(); try { if (token == null) { String accountName = preferences.getAccountName(); if (accountName == null) { return false; } token = generateToken(accountName); preferences.setAuthToken(token); } boolean success = doAuthenticate(token); if (success) { Log.v(TAG, "Succesfully logged in."); return true; } } catch (IOException e) { throw e; } catch (Exception e) { Log.e(TAG, "Unable to send settings: " + e.toString()); e.printStackTrace(); preferences.setAccountName(null); // reset because authentication or unforeseen error return false; } Log.w(TAG, "Login failed, retrying... Retry count " + (retryCount + 1)); http_client = new DefaultHttpClient(); preferences.setAuthToken(null); if (retryCount >= maxRetryCount) { preferences.setAccountName(null); // reset because it's not accepted by the server return false; } return authenticate(retryCount + 1); } private String generateToken(String accountName) throws OperationCanceledException, AuthenticatorException, IOException { UserHelper uf = new UserHelper(); return uf.getAuthToken(activity, new Account(accountName, UserHelper.ACCOUNT_TYPE)); } private boolean doAuthenticate(String token) throws IOException { if (checkCookie()) return true; try { Log.v(TAG, "Authenticating..."); // Don't follow redirects http_client.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false); HttpGet http_get = new HttpGet(serverUrls.get(ServerTarget.Authenticate) + token); HttpResponse response; response = http_client.execute(http_get); EntityUtils.toString(response.getEntity()); // read response to prevent warning int statusCode = response.getStatusLine().getStatusCode(); if (statusCode != 302) { Log.w(TAG, "No redirect, login failed. Status code: " + statusCode); return false; } else { Log.v(TAG, "Redirected, OK. Status code: " + statusCode); } return checkCookie(); } finally { if (http_client != null) http_client.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, true); } } private boolean checkCookie() { for (Cookie c : http_client.getCookieStore().getCookies()) { if (c.getName().equals("SACSID")) { Log.v(TAG, "Found SACSID cookie"); if (!c.isExpired(new Date())) { return true; } else { Log.w(TAG, "SACSID cookie expired"); } } } Log.w(TAG, "No valid SACSID cookie found"); http_client.getCookieStore().clear(); return false; } public ServerResponse post(MessageToServer message, ServerTarget target) throws IOException { HttpPost httpPost = new HttpPost(serverUrls.get(target)); httpPost.setEntity(new StringEntity(message.getHttpString())); HttpResponse response = http_client.execute(httpPost); int statusCode = response.getStatusLine().getStatusCode(); String responseString = EntityUtils.toString(response.getEntity()); ServerResponse serverResponse; serverResponse = new ServerResponse(statusCode, responseString); if (serverResponse.wasSuccesful()) { Log.i(TAG, "Settings sent to server"); } else { Log.e(TAG, "Unable to send settings! Response status code: " + statusCode + ", response string: " + responseString); } return serverResponse; } public ServerResponse get(MessageToServer message, ServerTarget target) throws IOException { String url = serverUrls.get(target); url = buildUrlWithParameters(url, message.getMap()); HttpGet httpGet = new HttpGet(url); HttpResponse response = http_client.execute(httpGet); int statusCode = response.getStatusLine().getStatusCode(); String responseString = EntityUtils.toString(response.getEntity()); ServerResponse serverResponse; if (target == ServerTarget.Message) serverResponse = new MessageServerResponse(statusCode, responseString); else serverResponse = new ServerResponse(statusCode, responseString); if (serverResponse.wasSuccesful()) { Log.i(TAG, "Data fetched from server, target type " + target); } else { Log.e(TAG, "Unable to fetch data from server! Response status code: " + statusCode + ", response string: " + responseString); } return serverResponse; } private static String buildUrlWithParameters(String url, Map<String, String> parameters) { if (!url.endsWith("?")) url += "?"; List<NameValuePair> params = new ArrayList<NameValuePair>(); for (Entry<String, String> entry : parameters.entrySet()) { params.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); } String paramString = URLEncodedUtils.format(params, "utf-8"); url += paramString; return url; } }