使用OKHttp3 get请求 , post请求

1 首先需要创建一个OKHttpClient 

可以直接new一个  

OkHttpClient client = new OkHttpClient()  

更多的是用builder构造一个 (那个addInterceptor方法是添加拦截器 , 可以不写,具体的baidu, bing, sogou)

private void buildHttpClient(){  
        this.client = new OkHttpClient.Builder()  
                .addInterceptor(new Interceptor() {  
                    public Response intercept(Chain chain) throws IOException {  
                        Request request = chain.request();  
                        Response response = chain.proceed(request);  
                        return response;  
                    }  
                })  
                .connectTimeout(4000, TimeUnit.MILLISECONDS)  
                .readTimeout(4000,TimeUnit.MILLISECONDS)  
                .writeTimeout(4000, TimeUnit.MILLISECONDS)  
                .build();  
}  

2 GET 请求

private void get(){  
        /* 如果需要参数 , 在url后边拼接 :  ?a=aaa&b=bbb..... */  
        Request request = new Request.Builder().url("http://192.168.10.117:8080/test").build();  
        client.newCall(request).enqueue(new Callback() {  
            public void onResponse(Call call, final Response response) throws IOException {  
                final String result = response.body().string();  
                final boolean ok = response.isSuccessful();  
                runOnUiThread(new Runnable() {  
                    public void run(){  
                        Toast.makeText(OKHttpActivity.this, result, Toast.LENGTH_SHORT).show();  
                    }  
                });  
            }  
            public void onFailure(Call call, IOException e) {  
                runOnUiThread(new Runnable() {  
                    public void run() {  
                        Toast.makeText(OKHttpActivity.this, "error", Toast.LENGTH_SHORT).show();  
                    }  
                });  
            }  
        });  
    }  

3 POST 请求

private void post(){  
    FormBody.Builder builder = new FormBody.Builder();  
    /* 添加两个参数 */  
    builder.add("p","我勒个去").add("a","hello");  
    FormBody body = builder.build();  
    Request request = new Request.Builder().url("http://192.168.10.117:8080/test").post(body).build();  
  
    /* 下边和get一样了 */  
    client.newCall(request).enqueue(new Callback() {  
        public void onResponse(Call call, Response response) throws IOException {  
            final  String bodyStr = response.body().string();  
            final boolean ok = response.isSuccessful();  
            runOnUiThread(new Runnable() {  
                public void run() {  
                    if(ok){  
                        Toast.makeText(OKHttpActivity.this, bodyStr, Toast.LENGTH_SHORT).show();  
                    }else{  
                        Toast.makeText(OKHttpActivity.this, "server error : " + bodyStr, Toast.LENGTH_SHORT).show();  
                    }  
                }  
            });  
        }  
        public void onFailure(Call call,final IOException e) {  
            runOnUiThread(new Runnable() {  
                public void run() {  
                    Toast.makeText(OKHttpActivity.this, "error : "+e.toString(), Toast.LENGTH_SHORT).show();  
                }  
            });  
        }  
    });  

4 多文件上传

private void upFile(){  
    /* 第一个要上传的file */  
    File file1 = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/a.jpg");  
    RequestBody fileBody1 = RequestBody.create(MediaType.parse("application/octet-stream") , file1);  
    String file1Name = "testFile1.txt";  
  
    /* 第二个要上传的文件,这里偷懒了,和file1用的一个图片 */  
    File file2 = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/a.jpg");  
    RequestBody fileBody2 = RequestBody.create(MediaType.parse("application/octet-stream") , file2);  
    String file2Name = "testFile2.txt";  
  
  
    /* form的分割线,自己定义 */  
    String boundary = "xx--------------------------------------------------------------xx";  
  
    MultipartBody mBody = new MultipartBody.Builder(boundary).setType(MultipartBody.FORM)  
            /* 上传一个普通的String参数 , key 叫 "p" */  
            .addFormDataPart("p" , "你大爷666")  
            /* 底下是上传了两个文件 */  
            .addFormDataPart("file" , file1Name , fileBody1)  
            .addFormDataPart("file" , file2Name , fileBody2)  
            .build();  
  
    /* 下边的就和post一样了 */  
    Request request = new Request.Builder().url("http://192.168.10.117:8080/test").post(mBody).build();  
    client.newCall(request).enqueue(new Callback() {  
        public void onResponse(Call call, Response response) throws IOException {  
            final  String bodyStr = response.body().string();  
            final boolean ok = response.isSuccessful();  
            runOnUiThread(new Runnable() {  
                public void run() {  
                    if(ok){  
                        Toast.makeText(OKHttpActivity.this, bodyStr, Toast.LENGTH_SHORT).show();  
                    }else{  
                        Toast.makeText(OKHttpActivity.this, "server error : " + bodyStr, Toast.LENGTH_SHORT).show();  
                    }  
                }  
            });  
        }  
        public void onFailure(Call call, final IOException e) {  
            runOnUiThread(new Runnable() {  
                public void run() {  
                    Toast.makeText(OKHttpActivity.this, e.toString(), Toast.LENGTH_SHORT).show();  
                }  
            });  
        }  
    });  
}  

二.简单封装

简单封装了okhttp3的工具类以便于以后直接拿来使用。

使用的okhttp版本为:

compile 'com.squareup.okhttp3:okhttp:3.8.1'
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();
                    }
                });
            }
        });

    }

 

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值