1. 程式人生 > >okhttp3簡單封裝GET和POST請求工具類

okhttp3簡單封裝GET和POST請求工具類

簡單封裝了okhttp3的工具類以便於以後直接拿來使用。

使用的okhttp版本為:

compile 'com.squareup.okhttp3:okhttp:3.8.1'

該工具類的功能如下:

  • Get請求,同步方式獲取網路資料
  • Post請求,同步方式獲取資料
  • Get請求,非同步方式獲取網路資料
  • Post請求,非同步方式獲取資料
  • 支援HTTPS請求,自動跳過證書驗證
  • 判斷當前網路是否可用

其中Post請求提交的是鍵值對<String,String>

1. 完整程式碼

import android.content.Context;
import android.net.ConnectivityManager;
import
android.net.NetworkInfo; import android.util.Log; import java.io.IOException; import java.security.SecureRandom; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.Iterator; import java.util.Map; import java.util.concurrent.TimeUnit; import javax.net.ssl.HostnameVerifier; import
javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import okhttp3.Call; import okhttp3.Callback; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import
okhttp3.Response; /** * Created by fxjzzyo on 2017/7/12. */ public class NetUtils { private static final byte[] LOCKER = new byte[0]; private static NetUtils mInstance; private OkHttpClient mOkHttpClient; private NetUtils() { okhttp3.OkHttpClient.Builder ClientBuilder=new okhttp3.OkHttpClient.Builder(); ClientBuilder.readTimeout(20, TimeUnit.SECONDS);//讀取超時 ClientBuilder.connectTimeout(6, TimeUnit.SECONDS);//連線超時 ClientBuilder.writeTimeout(60, TimeUnit.SECONDS);//寫入超時 //支援HTTPS請求,跳過證書驗證 ClientBuilder.sslSocketFactory(createSSLSocketFactory()); ClientBuilder.hostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }); mOkHttpClient=ClientBuilder.build(); } /** * 單例模式獲取NetUtils * @return */ public static NetUtils getInstance() { if (mInstance == null) { synchronized (LOCKER) { if (mInstance == null) { mInstance = new NetUtils(); } } } return mInstance; } /** * get請求,同步方式,獲取網路資料,是在主執行緒中執行的,需要新起執行緒,將其放到子執行緒中執行 * @param url * @return */ public Response getDataSynFromNet(String url) { //1 構造Request Request.Builder builder = new Request.Builder(); Request request=builder.get().url(url).build(); //2 將Request封裝為Call Call call = mOkHttpClient.newCall(request); //3 執行Call,得到response Response response = null; try { response = call.execute(); } catch (IOException e) { e.printStackTrace(); } return response; } /** * post請求,同步方式,提交資料,是在主執行緒中執行的,需要新起執行緒,將其放到子執行緒中執行 * @param url * @param bodyParams * @return */ public Response postDataSynToNet(String url,Map<String,String> bodyParams) { //1構造RequestBody RequestBody body=setRequestBody(bodyParams); //2 構造Request Request.Builder requestBuilder = new Request.Builder(); Request request = requestBuilder.post(body).url(url).build(); //3 將Request封裝為Call Call call = mOkHttpClient.newCall(request); //4 執行Call,得到response Response response = null; try { response = call.execute(); } catch (IOException e) { e.printStackTrace(); } return response; } /** * 自定義網路回撥介面 */ public interface MyNetCall{ void success(Call call, Response response) throws IOException; void failed(Call call, IOException e); } /** * get請求,非同步方式,獲取網路資料,是在子執行緒中執行的,需要切換到主執行緒才能更新UI * @param url * @param myNetCall * @return */ public void getDataAsynFromNet(String url, final MyNetCall myNetCall) { //1 構造Request Request.Builder builder = new Request.Builder(); Request request=builder.get().url(url).build(); //2 將Request封裝為Call Call call = mOkHttpClient.newCall(request); //3 執行Call call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { myNetCall.failed(call,e); } @Override public void onResponse(Call call, Response response) throws IOException { myNetCall.success(call,response); } }); } /** * post請求,非同步方式,提交資料,是在子執行緒中執行的,需要切換到主執行緒才能更新UI * @param url * @param bodyParams * @param myNetCall */ public void postDataAsynToNet(String url, Map<String,String> bodyParams, final MyNetCall myNetCall) { //1構造RequestBody RequestBody body=setRequestBody(bodyParams); //2 構造Request Request.Builder requestBuilder = new Request.Builder(); Request request = requestBuilder.post(body).url(url).build(); //3 將Request封裝為Call Call call = mOkHttpClient.newCall(request); //4 執行Call call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { myNetCall.failed(call,e); } @Override public void onResponse(Call call, Response response) throws IOException { myNetCall.success(call,response); } }); } /** * post的請求引數,構造RequestBody * @param BodyParams * @return */ private RequestBody setRequestBody(Map<String, String> BodyParams){ RequestBody body=null; okhttp3.FormBody.Builder formEncodingBuilder=new okhttp3.FormBody.Builder(); if(BodyParams != null){ Iterator<String> iterator = BodyParams.keySet().iterator(); String key = ""; while (iterator.hasNext()) { key = iterator.next().toString(); formEncodingBuilder.add(key, BodyParams.get(key)); Log.d("post http", "post_Params==="+key+"===="+BodyParams.get(key)); } } body=formEncodingBuilder.build(); return body; } /** * 判斷網路是否可用 * @param context * @return */ public static boolean isNetworkAvailable(Context context) { ConnectivityManager cm = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); if (cm == null) { } else { //如果僅僅是用來判斷網路連線 //則可以使用cm.getActiveNetworkInfo().isAvailable(); NetworkInfo[] info = cm.getAllNetworkInfo(); if (info != null) { for (int i = 0; i < info.length; i++) { if (info[i].getState() == NetworkInfo.State.CONNECTED) { return true; } } } } return false; } /** * 生成安全套接字工廠,用於https請求的證書跳過 * @return */ public SSLSocketFactory createSSLSocketFactory() { SSLSocketFactory ssfFactory = null; try { SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, new TrustManager[]{new TrustAllCerts()}, new SecureRandom()); ssfFactory = sc.getSocketFactory(); } catch (Exception e) { } return ssfFactory; } /** * 用於信任所有證書 */ class TrustAllCerts implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } } }

2. 用法舉例

推薦使用非同步請求,因為已經把網路請求自動放到子執行緒了,用起來稍簡單。而同步請求還需要自己new Thread+handler來做,幾乎和原始的網路請求沒區別了。因此這裡舉例就只舉非同步請求了。

非同步GET請求

點選按鈕登入

  public void login(View view) {
  final String account = etAccount.getText().toString();
  final String pass = etPassword.getText().toString();
  if (account.isEmpty() || pass.isEmpty()) {
    Toast.makeText(this, "使用者名稱或密碼不能為空!", Toast.LENGTH_SHORT).show();
           return;
       }
       if(!Global.isNetAvailable)
       {
           Toast.makeText(this, "網路不可用!", Toast.LENGTH_SHORT).show();
           return;
       }
       //進度條
       loginProgress.setVisibility(View.VISIBLE);
       //獲取網路工具類例項
       NetUtils netUtils = NetUtils.getInstance();
       //請求網路,一句程式碼搞定
       netUtils.getDataAsynFromNet(Global.LOGIN + "?username=" + account + "&password=" + pass,
               new NetUtils.MyNetCall() {
                   @Override
                   public void success(Call call, Response response) throws IOException {
                       Log.i("tag", "success");
                       String result = response.body().string();
                       final ResponseBean responseBean = JSON.parseObject(result, ResponseBean.class);

                       if (responseBean != null) {
                           runOnUiThread(new Runnable() {
                               @Override
                               public void run() {
                                   loginProgress.setVisibility(View.GONE);
                                   String errcode = responseBean.getErrcode();
                                   if (errcode.equals("0")) {//登入成功
                                       //記錄學號
                                       Global.account = account;
                                       //儲存使用者名稱密碼
                                       saveUserName(account, pass);

                                       Intent intent = new Intent(LoginActivity.this, MainActivity.class);
                                       startActivity(intent);
                                       LoginActivity.this.finish();
                                   } else {
                                       Toast.makeText(LoginActivity.this, "請求失敗!錯誤程式碼: " + errcode, Toast.LENGTH_SHORT).show();
                                   }

                               }
                           });

                       }
                   }

                   @Override
                   public void failed(Call call, IOException e) {
                       Log.i("tag", "failed");
                       runOnUiThread(new Runnable() {
                           @Override
                           public void run() {
                               loginProgress.setVisibility(View.GONE);
                               Toast.makeText(LoginActivity.this, "請求失敗!", Toast.LENGTH_SHORT).show();
                           }
                       });
                   }
               }

       );

   }

非同步POST請求

點選按鈕,提交資料

public void postSelect() {
        //確保選擇了樓號
        if (tvTargetBuilding.getText().toString().isEmpty()) {
            Toast.makeText(getActivity(),"請選擇樓號!",Toast.LENGTH_SHORT).show();
            return;
        }
        //構造請求引數
        Map<String, String> reqBody = new ConcurrentSkipListMap<>();
        reqBody.put("num", "1");
        reqBody.put("stuid", Global.account);
        reqBody.put("buildingNo", selectBuilding + "");
        //獲取網路請求工具類例項
        NetUtils netUtils = NetUtils.getInstance();
        //提交資料
        netUtils.postDataAsynToNet(Global.SELECT_ROOM, reqBody, new NetUtils.MyNetCall() {
            @Override
            public void success(Call call, Response response) throws IOException {
                Log.i("tag", "success");
                String result = response.body().string();
                Log.i("tag", "result: " + result);
                //解析資料
                JSONObject jsonObject1 = JSON.parseObject(result);
                if (jsonObject1 != null) {
                    final int error_code = jsonObject1.getIntValue("error_code");

                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Log.i("tag", "errcode: " + error_code);
                            if (error_code == 0) {//提交成功
                                Toast.makeText(getActivity(), "選擇成功!", Toast.LENGTH_SHORT).show();
                                //跳轉到selectSuccessfragment
                                MainActivity.mainActivityInstance.switchFragment(getParentFragment(),SelectSuccessFragment.newInstance("", ""));
                            } else {
                                Toast.makeText(getActivity(), "選擇失敗!錯誤程式碼: " + error_code, Toast.LENGTH_SHORT).show();
                            }

                        }
                    });

                }
            }
            @Override
            public void failed(Call call, IOException e) {
                Log.i("tag", "failed");
                getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(getActivity(), "請求失敗!", Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });

    }

什麼?還嫌程式碼太長?

其實很短的,除去註釋和列印的日誌以及一些不相干的部分(我這裡的是一個實際的專案,所以涉及到一些其他的東西),你會發現程式碼很少,核心的程式碼就是一句。(這時候你可能要說,哼,是一句,但一句有十多行。。。拜託~不要那麼懶啦好不好 -_-|||)

要注意的是獲取資料後,更新UI要在主執行緒中。我這裡使用的是runOnUiThread也可以用Handler。

用Handler後你會發現這一部分的程式碼很少了,因為只需要把獲取的資料用Message傳送到Handler處理就好了,這樣就把程式碼分散開了

runOnUiThread的好處是很直接,不過看起來程式碼都堆到一起,其實很方便的。

完結,撒花~

相關推薦

okhttp3簡單封裝GETPOST請求工具

簡單封裝了okhttp3的工具類以便於以後直接拿來使用。 使用的okhttp版本為: compile 'com.squareup.okhttp3:okhttp:3.8.1' 該工具類的功能如下: Get請求,同步方式獲取網路資料 Post請求,同步

[Java]自定義Jar庫,Http簡單GetPost請求封裝

最近寫Android程式頻繁用到Http的Get和Post、請求,每次寫一個專案都要重新URL --> URLConnection實在是太麻煩,乾脆,自己封裝了一個。 分別處理Get和Post簡

Java HttpClient4.2.x版本getpost請求工具

ont char cat time exec con lai pla names 公司業務需要,跟很多公司合作,經常需要請求外部http接口,而項目架構是一個比較老的框架整合,僅http請求的工具類就很多個,顯得雜亂無章; 有些接口測試時,對方做了IP白名單限制的,ZIP壓

Java 讀取get post 介面 工具整理

package cn.ijiami.mamp.manage.util; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.JS

簡單封裝了一個OKHttp的工具 非同步get請求和post請求

package com.example.okhttp.OkHttp; import android.os.Handler; import android.os.Looper; import android.util.Log; import com.example.okhttp.Con

使用okhttp3getpost請求工具

import okhttp3.*; import org.apache.ibatis.annotations.Param; import java.io.IOException; import java.util.Map; /** * 用於http請求的工具類 * 使用okhtt

簡單封裝Http的GetPost請求

public class HttpUtil { private HttpUtil() { } /** * get方法請求資料 * * @param url 請求地址 * @param params 請求引數 * @pa

java封裝httpClient工具(支援httphttps,包含getpost請求

網上有關方法非常多,但相對較零散,有些只支援http或https中的一種,或者只有get或post中的一種。以下對httpclient工具做了比較全面的封裝,支援http和https,包含get和post請求。 maven匯入的jar包有: <dependency&g

封裝curl的getpost請求

else 請求 enc con code urn gpo sta url /** * GET 請求 * @param string $url */ function http_get($url){ $oCurl = curl_init(); if(s

原生ajax的請求封裝getpost

取數 發送 text 對象 console xmlhttp UC var cat 一個完整的AJAX請求包括五個步驟:   1.創建XMLHTTPRequest對象   2.使用open方法創建http請求,並設置請求地址   3.設置發送的數據,開始和服務器端交互   4

java的HttpURLConnection封裝好的GET/POST請求工具

import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream;

Retrofit網路請求封裝公共引數GETPOST請求

public interface ApiService {    /**     * 無參get請求     * http://service.meiyinkeqiu.com/service/ads/cptj     *     * @return     */    //通

Http的getpost請求簡單應用

網路請求中需要遵循http協議,而http有許多方法,大家一般最常用的就是post和get請求方法了! 其中,post和get都可以向伺服器傳送和請求資料,而我們一般都習慣用get請求資料,post傳送資料!get方法是把資料拼接到請求行裡面,我們可以直接看到

發送getpost請求時常用的content-type

encode json數據格式 ima for www 下載 orm 文件上傳 服務器 常見的媒體格式類型如下: text/html : HTML格式 text/plain :純文本格式 text/xml : XML格式

HttpClient GETPOST請求

pri execute public methods gre col esp odt stringbu package com.rogue.hclient; import java.io.BufferedReader; import java.io.IOExceptio

http基本getpost請求

read exce pen timeout etc builder pri void tin get請求: private static void httpGet(){ BufferedReader br = null; HttpU

GETPOST請求的區別

cat nal 賬號 span asc 交互 cap 開發 code GET和POST請求的區別 GET請求GET /books/?sex=man&name=Professional HTTP/1.1Host: www.wrox.comUser-Agent: Mo

python request 接口測試getpost請求

.post .get access username int 用戶 post請求 運行 開發 開發IDE:pycharm python:2.7.10 get請求 # coding: UTF-8 #兼容中文字符,如果沒有這句,程序中有中文字符時,運行會報錯import

小程序的getpost請求頭的區別

type www 成功 ava form brush quest -type function 小程序在使用wx.request()接口 時 header 請求頭默認是這樣的 wx.request({ url: ‘test.php‘, //僅為示例,並非真實的接口

php-getpost請求

output class ray 工作日 打印 init print bsp clas 1.get請求 <?php //判斷20130101是否是工作日 //工作日對應結果為 0, 休息日對應結果為 1, 節假日對應的結果為 2; $url=‘http://www