package parse; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.ProtocolVersion; import org.apache.http.StatusLine; import org.apache.http.entity.BasicHttpEntity; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicHttpResponse; import org.apache.http.message.BasicStatusLine; import org.apache.http.protocol.HTTP; public class BmobHttpUtils { // TODO Your Application ID private static final String APP_ID = "Your Application ID"; // TODO Your REST API Key private static final String REST_API_KEY = "Your Application ID"; private static final String HEADER_CONTENT_TYPE = "Content-Type"; private static final String CHARSET = "UTF-8"; /** * Supported request methods. */ public interface Method { int GET = 0; int POST = 1; } public static String getString(String url) throws Exception { return getOrPostString(Method.GET, url, null); } public static String postString(String url, Map<String, String> postParams) throws Exception { return getOrPostString(Method.POST, url, postParams); } private static String getOrPostString(int method, String url, Map<String, String> postParams) throws Exception { HashMap<String, String> map = new HashMap<String, String>(); // bmob header map.put("X-Bmob-Application-Id", APP_ID); map.put("X-Bmob-REST-API-Key", REST_API_KEY); map.put("Content-Type", "application/json"); URL parsedUrl = new URL(url); HttpURLConnection connection = openConnection(parsedUrl); for (String headerName : map.keySet()) { connection.addRequestProperty(headerName, map.get(headerName)); } setConnectionParametersForRequest(connection, method, postParams); // Initialize HttpResponse with data from the HttpURLConnection. ProtocolVersion protocolVersion = new ProtocolVersion("HTTP", 1, 1); int responseCode = connection.getResponseCode(); if (responseCode == -1) { // -1 is returned by getResponseCode() if the response code could // not be retrieved. // Signal to the caller that something was wrong with the // connection. throw new IOException( "Could not retrieve response code from HttpUrlConnection."); } StatusLine responseStatus = new BasicStatusLine(protocolVersion, connection.getResponseCode(), connection.getResponseMessage()); BasicHttpResponse response = new BasicHttpResponse(responseStatus); response.setEntity(entityFromConnection(connection)); for (Entry<String, List<String>> header : connection.getHeaderFields().entrySet()) { if (header.getKey() != null) { Header h = new BasicHeader(header.getKey(), header.getValue() .get(0)); response.addHeader(h); } } Header contentTypeHeader = response.getHeaders(HTTP.CONTENT_TYPE)[0]; String responseCharset = parseCharset(contentTypeHeader); byte[] bytes = entityToBytes(response.getEntity()); String responseContent = new String(bytes, responseCharset); return responseContent; } /** * Returns the charset specified in the Content-Type of this header, or the * HTTP default (utf-8) if none can be found. */ private static String parseCharset(Header contentTypeHeader) { String contentType = contentTypeHeader.getValue(); if (contentType != null) { String[] params = contentType.split(";"); for (int i = 1; i < params.length; i++) { String[] pair = params[i].trim().split("="); if (pair.length == 2) { if (pair[0].equals("charset")) { return pair[1]; } } } } return "utf-8"; } private static byte[] entityToBytes(HttpEntity entity) throws IOException { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; try { InputStream in = entity.getContent(); int count; while ((count = in.read(buffer)) != -1) { bytes.write(buffer, 0, count); } } finally { bytes.close(); } return bytes.toByteArray(); } /** * Initializes an {@link HttpEntity} from the given * {@link HttpURLConnection}. * * @param connection * @return an HttpEntity populated with data from <code>connection</code>. */ private static HttpEntity entityFromConnection(HttpURLConnection connection) { BasicHttpEntity entity = new BasicHttpEntity(); InputStream inputStream; try { inputStream = connection.getInputStream(); } catch (IOException ioe) { inputStream = connection.getErrorStream(); } entity.setContent(inputStream); entity.setContentLength(connection.getContentLength()); entity.setContentEncoding(connection.getContentEncoding()); entity.setContentType(connection.getContentType()); return entity; } /** * Opens an {@link HttpURLConnection} with parameters. * * @param url * @return an open connection * @throws IOException */ private static HttpURLConnection openConnection(URL url) throws IOException { HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setConnectTimeout(20 * 1000); connection.setReadTimeout(20 * 1000); connection.setUseCaches(false); connection.setDoInput(true); // // use caller-provided custom SslSocketFactory, if any, for HTTPS // if ("https".equals(url.getProtocol()) && mSslSocketFactory != null) { // ((HttpsURLConnection)connection).setSSLSocketFactory(mSslSocketFactory); // } return connection; } /** * Converts <code>params</code> into an application/x-www-form-urlencoded * encoded string. */ private static byte[] encodeParameters(Map<String, String> params, String paramsEncoding) { StringBuilder encodedParams = new StringBuilder(); try { for (Map.Entry<String, String> entry : params.entrySet()) { encodedParams.append(URLEncoder.encode(entry.getKey(), paramsEncoding)); encodedParams.append('='); encodedParams.append(URLEncoder.encode(entry.getValue(), paramsEncoding)); encodedParams.append('&'); } return encodedParams.toString().getBytes(paramsEncoding); } catch (UnsupportedEncodingException uee) { throw new RuntimeException("Encoding not supported: " + paramsEncoding, uee); } } /** * Returns the raw POST body to be sent. */ private static byte[] getPostBody(Map<String, String> postParams) { if (postParams != null && postParams.size() > 0) { return encodeParameters(postParams, CHARSET); } return null; } private static void setConnectionParametersForRequest( HttpURLConnection connection, int method, Map<String, String> postParams) throws IOException { switch (method) { case Method.GET: connection.setRequestMethod("GET"); break; case Method.POST: byte[] postBody = getPostBody(postParams); if (postBody != null) { // Prepare output. There is no need to set Content-Length // explicitly, // since this is handled by HttpURLConnection using the size of // the prepared // output stream. connection.setDoOutput(true); connection.setRequestMethod("POST"); DataOutputStream out = new DataOutputStream( connection.getOutputStream()); out.write(postBody); out.close(); } break; } } }