写点什么

okhttp3 第一次使用

发布于: 2021 年 01 月 13 日
okhttp3 第一次使用

最近使用了 okhttp3 + mvvm 的架构框架,也了解了 volley,httpclient,async-http 等框架,这些框架之前有的使用过,比起 okhttp3 来说,okhttp3

有各种自定义拦截器,这里介绍下 okhttp 的各种方法吧。

request = new Request.Builder()

.url(API.baseurl + url + "?" + stringJson)

.header("ACCESS_TOKEN", Utils.getToken(activity))

.build();这是 get 请求,构造 request 时候,直接吧参数拼成 name=xx&pwd=xx 这种表单格式放在?后面。

RequestBody body;

if (stringJson == null) {

body = RequestBody.create("", JSON);

} else {

body = RequestBody.create(stringJson, JSON);

}

request = new Request.Builder()

.url(API.baseurl + url)

.post(body)

.header("ACCESS_TOKEN", Utils.getToken(activity))

.build();这是 post 请求,requestbody.create(stringjson,JSON),stringjson 是 json 格式的请求参数,后面的 JSON 是

public static final MediaType JSON = MediaType.get("application/json; charset=utf-8");

Content-Type(MediaType),即是 Internet Media Type,互联网媒体类型;也叫做 MIME 类型,在 Http 协议消息头中,使用 Content-Type 来表示

具体请求中的媒体类型信息。

用于定义网络文件的类型和网页的编码,决定文件接收方将以什么形式、什么编码读取这个文件。常见的媒体格式类型有:

text/html:HTML 格式

text/pain:纯文本格式

image/jpeg:jpg 图片格式

application/json:JSON 数据格式

application/octet-stream:二进制流数据(如常见的文件下载)

application/x-www-form-urlencoded:form 表单 encType 属性的默认格式,表单数据将以 key/value 的形式发送到服务端

multipart/form-data:表单上传文件的格式

返回使用 enqueue client.newCall(request).enqueue(new Callback() {

@Override

public void onFailure(Call call, IOException e) {

}

@Override

public void onResponse(Call call, Response response) throws IOException {

}

});

异步返回用这个方法,execute 同步阻塞调没用过 a。

初始化 okhttpclient 并设置默认信任所有证书,添加拦截器,为了不断更新 token 加在请求头给服务端,所以我的初始化代码是这样写的:

private OkHttpClient okhttpclient(Activity activity) {

try {

if (client == null) {

client = new OkHttpClient.Builder().

sslSocketFactory(createSSLSocketFactory(), new TrustAllCerts())

.hostnameVerifier(new TrustAllHostnameVerifier()).addInterceptor(interceptor(activity))

.build();

}

return client;

} catch (Exception e) {

Utils.log("", "", "okhttp https 连接问题");

return null;

}

}

拦截器就是为了拿到服务端 response 里面的 token 和打印各种请求和返回,代码如下:

public class HttpLogInterceptor implements Interceptor {

// private static final String TAG = HttpLogInterceptor.class.getSimpleName();

private final Charset UTF8 = Charset.forName("UTF-8");

private Activity activity;

public HttpLogInterceptor(Activity activity) {

this.activity = activity;

}


@Override

public Response intercept(Chain chain) throws IOException {

Request request = chain.request();

RequestBody requestBody = request.body();

String body = null;

if (requestBody != null) {

Buffer buffer = new Buffer();

requestBody.writeTo(buffer);

Charset charset = UTF8;

MediaType contentType = requestBody.contentType();

if (contentType != null) {

charset = contentType.charset(UTF8);

}

body = buffer.readString(charset);

}


Log.d("xuedi", "发送请求: method:" + request.method()

+ "\nurl:" + request.url()

+ "\n 请求头:" + request.headers()

+ "\n 请求参数: " + body);

long startNs = System.nanoTime();

Response response = chain.proceed(request);

long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);

if (response.header("ACCESS_TOKEN")!=null) {

UserLogin.getInstance().setToken(response.header("ACCESS_TOKEN"));

SharePref.put(activity, API.token, response.header("ACCESS_TOKEN"));

}

ResponseBody responseBody = response.body();

String rBody;

BufferedSource source = responseBody.source();

source.request(Long.MAX_VALUE);

Buffer buffer = source.buffer();


Charset charset = UTF8;

MediaType contentType = responseBody.contentType();

if (contentType != null) {

try {

charset = contentType.charset(UTF8);

} catch (UnsupportedCharsetException e) {

e.printStackTrace();

}

}

rBody = buffer.clone().readString(charset);


Log.d("xuedi", "收到: method:" + request.method()+

"\n 响应 header:"+response.header("ACCESS_TOKEN")

+"\n 响应 url:"+response.request().url()

+ "\n 响应 body: " + rBody);

return response;

}

这里面就是重写的 intercept(Chain chain),chain.request 和 chain.response 拿到就可以打印了,这是 Chain 接口方法:

public interface Chain {

public abstract fun call(): okhttp3.Call


public abstract fun connectTimeoutMillis(): kotlin.Int


public abstract fun connection(): okhttp3.Connection?


public abstract fun proceed(request: okhttp3.Request): okhttp3.Response


public abstract fun readTimeoutMillis(): kotlin.Int


public abstract fun request(): okhttp3.Request


public abstract fun withConnectTimeout(timeout: kotlin.Int, unit: java.util.concurrent.TimeUnit): okhttp3.Interceptor.Chain


public abstract fun withReadTimeout(timeout: kotlin.Int, unit: java.util.concurrent.TimeUnit): okhttp3.Interceptor.Chain


public abstract fun withWriteTimeout(timeout: kotlin.Int, unit: java.util.concurrent.TimeUnit): okhttp3.Interceptor.Chain


public abstract fun writeTimeoutMillis(): kotlin.Int

}

拿到保存在本地,然后返回给服务端,这就是一次完整的请求。

当然还有多类型上传,formbody 上传等等。https://square.github.io/okhttp/https

这是官方网址,可以去看看。


用户头像

编程随想 2021.01.12 加入

Android开发

评论

发布
暂无评论
okhttp3 第一次使用