Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I split the logic of HttpUrlConnection into multiple methods?

I have multiple Activities each of which gets different data from different URLs and different HTTP methods like POST, GET, PUT, DELETE, etc. Some requests have header data while some have Body, some may have both. I am using a single AsyncTask class with multiple constructors to pass data from the Activities such that I can add them to the HttpUrlConnection instance.

I tried this tutorial: http://cyriltata.blogspot.in/2013/10/android-re-using-asynctask-class-across.html.

But the above tutorial uses HttpClient and NameValuePair. I replaced NameValuePair with Pair. But I am finding it difficult to implement the same logic using HttpUrlConnection as I need to add multiple POST data and headers to my request.

But the String returned is empty. How do I implement this scenario properly?

Full code:

public class APIAccessTask extends AsyncTask<String,Void,String> {
URL requestUrl;
Context context;
HttpURLConnection urlConnection;
List<Pair<String,String>> postData, headerData;
String method;
int responseCode = HttpURLConnection.HTTP_NOT_FOUND;


APIAccessTask(Context context, String requestUrl, String method){
    this.context = context;
    this.method = method;
    try {
        this.requestUrl = new URL(requestUrl);
    }
    catch(Exception ex){
        ex.printStackTrace();
    }
 }


APIAccessTask(Context context, String requestUrl, String method,    List<Pair<String,String>> postData,){
    this(context, requestUrl, method);
    this.postData = postData;
}

APIAccessTask(Context context, String requestUrl, String method, List<Pair<String,String>> postData,
              List<Pair<String,String>> headerData){
    this(context, requestUrl,method,postData);
    this.headerData = headerData;
}

@Override
protected void onPreExecute() {
    super.onPreExecute();
}

@Override
protected String doInBackground(String... params) {

    setupConnection();

    if(method.equals("POST"))
    {
        return httpPost();
    }

    if(method.equals("GET"))
    {
        return httpGet();
    }

    if(method.equals("PUT"))
    {
        return httpPut();
    }

    if(method.equals("DELETE"))
    {
        return httpDelete();
    }
    if(method.equals("PATCH"))
    {
        return httpPatch();
    }

    return null;
}

@Override
protected void onPostExecute(String result) {
    Toast.makeText(context,result,Toast.LENGTH_LONG).show();
    super.onPostExecute(result);
}

void setupConnection(){
    try {
        urlConnection = (HttpURLConnection) requestUrl.openConnection();
        urlConnection.setDoOutput(true);
        urlConnection.setDoInput(true);
        urlConnection.setChunkedStreamingMode(0);
        if(headerData != null){
            for (Pair pair: headerData)
            {
                urlConnection.setRequestProperty(pair.first.toString(), Base64.encodeToString(pair.second.toString().getBytes(),Base64.DEFAULT));
            }
        }
    }
    catch(Exception ex) {
        ex.printStackTrace();
    }

}

private String httpPost(){
    try{
        urlConnection.setRequestMethod("POST");
    }
    catch (Exception ex){
        ex.printStackTrace();

    return stringifyResponse();
}

String httpGet(){

    try{
        urlConnection.setRequestMethod("GET");
    }
    catch (Exception ex){
        ex.printStackTrace();
    }
    return stringifyResponse();
}

String httpPut(){

    try{
        urlConnection.setRequestMethod("PUT");
    }
    catch (Exception ex){
        ex.printStackTrace();
    }
    return stringifyResponse();
}

String httpDelete(){
    try{
        urlConnection.setRequestMethod("DELETE");
    }
    catch (Exception ex){
        ex.printStackTrace();
    }
    return stringifyResponse();

}

String httpPatch(){
    try{
        urlConnection.setRequestMethod("PATCH");
    }
    catch (Exception ex){
        ex.printStackTrace();
    }
    return stringifyResponse();

}

String stringifyResponse() {

    StringBuilder sb = new StringBuilder();
    try {
        OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
        writer.write(getQuery(postData));
        writer.flush();
        writer.close();
        out.close();

        urlConnection.connect();
        responseCode = urlConnection.getResponseCode();
        if (responseCode == 200) {
            InputStream in = new BufferedInputStream(urlConnection.getInputStream());
            BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
            String line = null;

            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        }

    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return sb.toString();
}


private String getQuery(List<Pair<String,String>> params) throws UnsupportedEncodingException{
    Uri.Builder builder = null;
    for (Pair pair : params)
    {
         builder = new Uri.Builder()
                .appendQueryParameter(pair.first.toString(), pair.second.toString());
                }
    return builder.build().getEncodedQuery();
}
}
like image 536
Shantanu Paul Avatar asked Oct 31 '22 12:10

Shantanu Paul


1 Answers

IMO, you can refer to my following sample code:

   /**         
     * HTTP request using HttpURLConnection
     *
     * @param method
     * @param address
     * @param header
     * @param mimeType
     * @param requestBody
     * @return
     * @throws Exception
     */
    public static URLConnection makeURLConnection(String method, String address, String header, String mimeType, String requestBody) throws Exception {
        URL url = new URL(address);

        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

        urlConnection.setDoInput(true);
        urlConnection.setDoOutput(!method.equals(HTTP_METHOD_GET));
        urlConnection.setRequestMethod(method);

        if (isValid(header)) {   // let's assume only one header here             
            urlConnection.setRequestProperty(KEYWORD_HEADER_1, header);
        }

        if (isValid(requestBody) && isValid(mimeType) && !method.equals(HTTP_METHOD_GET)) {
            urlConnection.setRequestProperty(KEYWORD_CONTENT_TYPE, mimeType);
            OutputStream outputStream = new BufferedOutputStream(urlConnection.getOutputStream());
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "utf-8");
            writer.write(requestBody);
            writer.flush();
            writer.close();
            outputStream.close();
        }

        urlConnection.connect();

        return urlConnection;
    }

the requestBody is made by using the following method:

    public static String buildRequestBody(Object content) {
        String output = null;
        if ((content instanceof String) ||
                (content instanceof JSONObject) ||
                (content instanceof JSONArray)) {
            output = content.toString();
        } else if (content instanceof Map) {
            Uri.Builder builder = new Uri.Builder();
            HashMap hashMap = (HashMap) content;
            if (isValid(hashMap)) {
                Iterator entries = hashMap.entrySet().iterator();
                while (entries.hasNext()) {
                    Map.Entry entry = (Map.Entry) entries.next();
                    builder.appendQueryParameter(entry.getKey().toString(), entry.getValue().toString());
                    entries.remove(); // avoids a ConcurrentModificationException
                }
                output = builder.build().getEncodedQuery();
            }
        } else if (content instanceof byte[]) {
            try {
                output = new String((byte[]) content, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }

        return output;
    }
}

Then, in your AsyncTask class, you can call:

       String url = "http://.......";
       HttpURLConnection urlConnection;
       Map<String, String> stringMap = new HashMap<>();           
       stringMap.put(KEYWORD_USERNAME, "bnk");
       stringMap.put(KEYWORD_PASSWORD, "bnk123");
       String requestBody = buildRequestBody(stringMap);
       try {
           urlConnection = (HttpURLConnection) Utils.makeURLConnection(HTTP_METHOD_POST, url, null, MIME_FORM_URLENCODED, requestBody);               
           if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
               // do something...
           } else {
               // do something...
           }
           ...
       } catch (Exception e) {
           e.printStackTrace();
       }

or

       String url = "http://.......";
       HttpURLConnection urlConnection;
       JSONObject jsonBody;                      
       String requestBody;
       try {
           jsonBody = new JSONObject();
           jsonBody.put("Title", "Android Demo");
           jsonBody.put("Author", "BNK");
           requestBody = Utils.buildRequestBody(jsonBody);
           urlConnection = (HttpURLConnection) Utils.makeURLConnection(HTTP_METHOD_POST, url, null, MIME_JSON, requestBody);               
           if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
               // do something...
           } else {
               // do something...
           }
           ...
       } catch (Exception e) {
           e.printStackTrace();
       }
like image 199
BNK Avatar answered Nov 09 '22 09:11

BNK