2015-12-22 2 views
5

मेरे पास कई यूआरएल और विभिन्न HTTP विधियों जैसे POST, GET, PUT, DELETE, आदि कुछ अनुरोधों में हेडर डेटा होता है जबकि कुछ में बॉडी होती है, कुछ में दोनों हो सकते हैं। मैं एक AsyncTask कक्षा का उपयोग कर रहा हूं जिसमें कई रचनाकारों के साथ गतिविधियां हैं, जिन्हें मैं HttpUrlConnection उदाहरण में जोड़ सकता हूं।मैं HttpUrlConnection के तर्क को कई तरीकों से कैसे विभाजित कर सकता हूं?

मैंने इस ट्यूटोरियल की कोशिश की: http://cyriltata.blogspot.in/2013/10/android-re-using-asynctask-class-across.html

लेकिन उपरोक्त ट्यूटोरियल HttpClient और NameValuePair का उपयोग करता है। मैंने NameValuePair को Pair के साथ बदल दिया। लेकिन मुझे HttpUrlConnection का उपयोग करके उसी तर्क को लागू करना मुश्किल लगता है क्योंकि मुझे अपने अनुरोध पर एकाधिक POST डेटा और शीर्षलेख जोड़ने की आवश्यकता है।

लेकिन वापस स्ट्रिंग खाली है। मैं इस परिदृश्य को सही ढंग से कैसे कार्यान्वित करूं?

पूर्ण कोड:

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(); 
} 
} 
+1

क्या आप अपना कोड जोड़ सकते हैं जहां आप अपने अनुरोध में एकाधिक पोस्ट डेटा जोड़ने की कोशिश कर रहे हैं। –

+2

आप जो पूछ रहे हैं उसे अस्पष्ट करें। एकाधिक POST नाम-मूल्य जोड़े या हेडर जोड़ने के लिए आपको कई विधियों की आवश्यकता नहीं है। – EJP

+0

आईएमओ, आपकी आवश्यकता के लिए, आप Google वॉली के स्रोत कोड का संदर्भ ले सकते हैं, जो 'HurCStction.java] पर' setConnectionParametersForRequest' से शुरू होता है (https://android.googlesource.com/platform/frameworks/volley/+/master/src/ मुख्य/जावा/कॉम/एंड्रॉइड/वॉली/टूलबॉक्स/HurlStack.java) – BNK

उत्तर

1

IMO, तुम मेरे निम्न नमूना कोड का उल्लेख कर सकते हैं:

/**   
    * 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; 
    } 

requestBody किया जाता है निम्नलिखित विधि का उपयोग कर: तब

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; 
    } 
} 

, आपके AsyncTask क्लास में, आप कॉल कर सकते हैं:

 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(); 
     } 

या

 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(); 
     } 
+0

'कनेक्ट() 'कॉल करने में थोड़ा देर हो चुकी है। * के बाद * आपने अनुरोध भेजा है। आपको वास्तव में 'कनेक्ट() 'बिल्कुल कॉल करने की आवश्यकता नहीं है। यह देखने में मुश्किल है कि यह खोजन का उत्तर कैसे देता है, जिसका अर्थ है 'एकाधिक विधियों में तोड़ना'। – EJP

+0

@EJP: मैं कनेक्ट() के बारे में आपसे सहमत हूं। "तोड़ने" के बारे में, यदि मैं ओपी की आवश्यकता को सही ढंग से समझता हूं, जब वह "प्राप्त करें" पास करता है, उदाहरण के लिए, "विधि" परम के लिए, यह एक GET अनुरोध है ... यदि "पोस्ट" पास हो गया है, तो यह एक POST अनुरोध है। – BNK

1

कुछ उफ़ अवधारणाओं को लागू यहाँ
के साथ एक कक्षा HttpCommunication है विशुद्ध रूप से अनुरोध भेजने और प्रतिक्रिया सर्वर से वापस पाने की देखभाल करेगी। जो के लिए नमूना कोड के रूप में इस प्रकार है

package com.example.sample; 

import java.io.BufferedReader; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.util.ArrayList; 

import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.NameValuePair; 
import org.apache.http.client.entity.UrlEncodedFormEntity; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.client.utils.URLEncodedUtils; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.apache.http.params.BasicHttpParams; 
import org.apache.http.params.HttpConnectionParams; 
import org.apache.http.params.HttpParams; 

public class HttpCommunication { 
    public String makeHttpRequest(String url, HttpMethods method, ArrayList<NameValuePair> requestParams, ArrayList<NameValuePair> postData) throws Exception { 

     InputStream inputStream = null; 
     String response = ""; 
     HttpParams httpParameters = new BasicHttpParams(); 

     /** 
     * Set the timeout in milliseconds until a connection is established. The default value is 
     * zero, that means the timeout is not used. 
     */ 
     int timeoutConnection = 15000; 
     HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection); 

     /** 
     * Set the default socket timeout (SO_TIMEOUT) in milliseconds which is the timeout for 
     * waiting for data. 
     */ 
     int timeoutSocket = 15000; 
     HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket); 

     DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters); 

     /** 
     * Check for request method 
     */ 
     if (method == HttpMethods.POST) { 
      HttpPost httpPost = new HttpPost(url); 

      if (requestParams != null && requestParams.size() > 0) { 
       httpPost.setEntity(new UrlEncodedFormEntity(requestParams)); 
      } 

      HttpResponse httpResponse = httpClient.execute(httpPost); 
      HttpEntity httpEntity = httpResponse.getEntity(); 
      inputStream = httpEntity.getContent(); 

     } else if (method == HttpMethods.GET) { 
      if (requestParams != null && requestParams.size() > 0) { 
       String paramString = URLEncodedUtils.format(requestParams, "utf-8"); 
       url += "?" + paramString; 
      } 

      HttpGet httpGet = new HttpGet(url); 

      HttpResponse httpResponse = httpClient.execute(httpGet); 
      HttpEntity httpEntity = httpResponse.getEntity(); 
      inputStream = httpEntity.getContent(); 
     } 

     BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8")); 
     StringBuilder sb = new StringBuilder(); 
     String line = null; 
     while ((line = reader.readLine()) != null) { 
      sb.append(line + "\n"); 
     } 
     inputStream.close(); 
     response = sb.toString(); 

     return response; 
    } 
} 

एक सार आधार वर्ग जो अपने आवेदन में सभी अंतर्निहित webservices के लिए एक टेम्पलेट के रूप में कार्य करेगा किया है। यह कक्षा अनुरोध भेजने के लिए एचटीपी कॉम्यूनिकेशन क्लास का उपयोग करेगी। अनुरोध AsyncTask से भेजे जाएंगे, इसलिए यह पूरी तरह से असीमित है। कक्षा अमूर्त विधियों को प्रदान करेगी जो कक्षाओं को ओवरराइड करना चाहिए और परिभाषाएं प्रदान करना चाहिए;
1. getUrl() - अच्छी तरह से स्वरूपित अनुरोध यूआरएल
2. getHttpMethod() - प्राप्त से HTTP विधि में से एक, पोस्ट, डाल, हटाएँ, PATCH
3. getRequestParams() - अनुरोध पैरामीटर (हेडर) यदि कोई।
4. getPostParams() - पोस्ट पैरा अगर कोई है।
5. parseResponse (स्ट्रिंग) - व्युत्पन्न कक्षाओं को प्राप्त प्रतिक्रिया को पार्स करने के लिए इस विधि की परिभाषा अवश्य देनी चाहिए।
6. सूचित करें त्रुटि (int) - व्युत्पन्न कक्षाओं को संचार में प्राप्त होने वाली त्रुटि को संसाधित करने के लिए इस विधि की परिभाषा अवश्य देनी चाहिए।

package com.example.sample; 
import java.util.ArrayList; 
import org.apache.http.NameValuePair; 
import android.os.AsyncTask; 
/** 
* This class is an abstract base class for all web services. 
*/ 
public abstract class BaseService { 
    protected abstract String getUrl(); 
    protected abstract HttpMethods getHttpMethod(); 
    protected abstract ArrayList<NameValuePair> getRequestParams(); 
    protected abstract ArrayList<NameValuePair> getPostParams(); 
    protected abstract void parseResponse(String response); 
    protected abstract void notifyError(int errorCode); 

    public void send() { 
     SendRequestTask sendRequestTask = new SendRequestTask(); 
     sendRequestTask.execute(); 
    } 

    private class SendRequestTask extends AsyncTask< Void, Void, Integer > { 
     @Override 
     protected Integer doInBackground(Void... params) { 
      try { 
       String url = getUrl(); 
       HttpMethods method = getHttpMethod(); 
       ArrayList<NameValuePair> httpParams = getRequestParams(); 
       ArrayList<NameValuePair> postParams = getPostParams(); 

       HttpCommunication httpCommunication = new HttpCommunication(); 
       String response = httpCommunication.makeHttpRequest(url, method, httpParams, postParams); 

       parseResponse(response); 
      } catch (Exception ex) { 
       ex.printStackTrace(); 
       notifyError(CommunicationError.ERROR_COMMUNICATION); 
      } 
      return 0; 
     } 
    } 
} 

यहाँ नमूना वेब सेवा वर्ग जो श्रेणी से ऊपर से ली गई है के लिए कोड है,

package com.example.sample; 
import java.util.ArrayList; 
import org.apache.http.NameValuePair; 
import org.apache.http.message.BasicNameValuePair; 
/** 
* This is a web service class to login. 
*/ 
public class SignIn extends BaseService { 
    private final String _emailId; 
    private final String _password; 
    private final String _signinUrl = "http://www.example.com/login.php"; 

    public SignIn(String userName, String password) { 
     _emailId = userName; 
     _password = null; 
    } 

    @Override 
    protected String getUrl() { 
     return _signinUrl; 
    } 

    @Override 
    protected ArrayList<NameValuePair> getRequestParams() { 
     ArrayList<NameValuePair> params = new ArrayList<NameValuePair>(); 
     params.add(new BasicNameValuePair("header1", "header1")); 
     params.add(new BasicNameValuePair("header2", "header2")); 
     return params; 
    } 

    @Override 
    protected ArrayList<NameValuePair> getPostParams() { 
     ArrayList<NameValuePair> params = new ArrayList<NameValuePair>(); 
     params.add(new BasicNameValuePair("email", _emailId)); 
     params.add(new BasicNameValuePair("password", _password)); 
     return params; 
    } 

    @Override 
    protected HttpMethods getHttpMethod() { 
     return HttpMethods.POST; 
    } 

    @Override 
    protected void parseResponse(String response) { 
     // Parse the response here 
    } 

    @Override 
    protected void notifyError(int errorCode) { 
     // Notify error to application 
    } 
} 

यहां बताया गया है कि आप साइनइन webservice का उपयोग कैसे कर सकते हैं;

SignIn signIn = new SignIn("[email protected]", "abc123"); 
signIn.send(); 

कृपया अपने एचटीपी कॉम्यूनिकेशन क्लास को निम्नानुसार संशोधित करें।

package com.example.sample; 

import java.io.BufferedReader; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.OutputStream; 
import java.net.HttpURLConnection; 
import java.net.URL; 
import java.util.ArrayList; 

import org.apache.http.NameValuePair; 

public class HttpCommunication { 
    private final int CONNECTION_TIMEOUT = 10 * 1000; 

    /** 
    * Default Constructor 
    */ 
    public HttpCommunication() { 

    } 

    public String makeHttpRequest(String strUrl, HttpMethods method, ArrayList<NameValuePair> requestParams, ArrayList<NameValuePair> postData) throws Exception { 

     HttpURLConnection connection = null; 
     InputStream inputStream = null; 
     URL url = null; 
     String response = null; 
     try { 
      url = new URL(strUrl); 
      connection = (HttpURLConnection) url.openConnection(); 
      connection.setConnectTimeout(CONNECTION_TIMEOUT); 
      connection.setReadTimeout(CONNECTION_TIMEOUT); 

      if (requestParams != null && requestParams.size() > 0) { 
       for (NameValuePair pair : requestParams) { 
        connection.setRequestProperty(pair.getName(), pair.getValue()); 
       } 
      } 

      connection.setDoInput(true); 
      connection.connect(); 
      if (method == HttpMethods.POST) { 
       OutputStream os = connection.getOutputStream(); 
       // Convert post data to string and then write it to outputstream. 
       String postDataStr = "test"; 
       os.write(postDataStr.getBytes()); 
       os.close(); 
      } 

      inputStream = connection.getInputStream(); 

      if (inputStream != null) { 
       BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8")); 
       StringBuilder sb = new StringBuilder(); 
       String line = null; 
       while ((line = reader.readLine()) != null) { 
        sb.append(line + "\n"); 
       } 
       response = sb.toString(); 
       inputStream.close(); 
      } 
      connection.disconnect(); 
     } catch (Exception e) { 
      if (connection != null) { 
       connection.disconnect(); 
      } 
     } 

     return response; 
    } 
} 
+0

मुझे पता है कि यह अपाचे 'HttpClient' द्वारा कैसे किया जा सकता है। जिसे एपीआई 22 के रूप में बहिष्कृत किया गया है। यदि आप 'HttpUrlConnection' के साथ कोड पोस्ट कर सकते हैं, तो यह उपयोगी होता। –

+0

कृपया संशोधित एचटीपी कॉम्यूनिकेशन क्लास का संदर्भ लें। आपको किसी अन्य वर्ग को बदलने की जरूरत नहीं है। – abidfs

संबंधित मुद्दे

 संबंधित मुद्दे