okhttp3使用
来源:互联网 发布:mac区域截屏保存在哪里 编辑:程序博客网 时间:2024/05/21 00:47
以下是我对okhttp使用的一些总结:
同步Get请求
private final OkHttpClient client = new OkHttpClient();public void run() throws Exception { Request request = new Request.Builder() .url("http://publicobject.com/helloworld.txt") .build(); Response response = client.newCall(request).execute(); if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); Headers responseHeaders = response.headers(); for (int i = 0; i < responseHeaders.size(); i++) { System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i)); } System.out.println(response.body().string());}
异步Get
private final OkHttpClient client = new OkHttpClient();public void run() throws Exception { Request request = new Request.Builder() .url("http://publicobject.com/helloworld.txt") .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Request request, Throwable throwable) { throwable.printStackTrace(); } @Override public void onResponse(Response response) throws IOException { if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); Headers responseHeaders = response.headers(); for (int i = 0; i < responseHeaders.size(); i++) { System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i)); } System.out.println(response.body().string()); } });}
提取响应头
private final OkHttpClient client = new OkHttpClient();public void run() throws Exception { Request request = new Request.Builder() .url("https://api.github.com/repos/square/okhttp/issues") .header("User-Agent", "OkHttp Headers.java") .addHeader("Accept", "application/json; q=0.5") .addHeader("Accept", "application/vnd.github.v3+json") .build(); Response response = client.newCall(request).execute(); if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); System.out.println("Server: " + response.header("Server")); System.out.println("Date: " + response.header("Date")); System.out.println("Vary: " + response.headers("Vary"));}
Post方式提交String
public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");private final OkHttpClient client = new OkHttpClient();public void run() throws Exception { //这种方式避免提交过长的字符串 String postBody = "" + "Releases\n" + "--------\n" + "\n" + " * _1.0_ May 6, 2013\n" + " * _1.1_ June 15, 2013\n" + " * _1.2_ August 11, 2013\n"; Request request = new Request.Builder() .url("https://api.github.com/markdown/raw") .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, postBody)) .build(); Response response = client.newCall(request).execute(); if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); System.out.println(response.body().string());}
Post方式提交流
public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");private final OkHttpClient client = new OkHttpClient();public void run() throws Exception { //这里重写了requestBody 的俩个方法,指定了它上传的类型,并且使用okio的BufferedSink 进行数据的提交 RequestBody requestBody = new RequestBody() { @Override public MediaType contentType() { return MEDIA_TYPE_MARKDOWN; } @Override public void writeTo(BufferedSink sink) throws IOException { sink.writeUtf8("Numbers\n"); sink.writeUtf8("-------\n"); for (int i = 2; i <= 997; i++) { sink.writeUtf8(String.format(" * %s = %s\n", i, factor(i))); } } private String factor(int n) { for (int i = 2; i < n; i++) { int x = n / i; if (x * i == n) return factor(x) + " × " + i; } return Integer.toString(n); } }; Request request = new Request.Builder() .url("https://api.github.com/markdown/raw") .post(requestBody) .build(); Response response = client.newCall(request).execute(); if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); System.out.println(response.body().string());}
Post方式提交文件
public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");private final OkHttpClient client = new OkHttpClient();public void run() throws Exception { File file = new File("README.md"); Request request = new Request.Builder() .url("https://api.github.com/markdown/raw") .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, file)) .build(); Response response = client.newCall(request).execute(); if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); System.out.println(response.body().string());}
Post方式提交表单
private final OkHttpClient client = new OkHttpClient();public void run() throws Exception { //使用FormEncodingBuilder来构建和HTML<form>标签相同效果的请求体。 //键值对将使用一种HTML兼容形式的URL编码来进行编码。 RequestBody formBody = new FormEncodingBuilder() .add("search", "Jurassic Park") .build(); Request request = new Request.Builder() .url("https://en.wikipedia.org/w/index.php") .post(formBody) .build(); Response response = client.newCall(request).execute(); if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); System.out.println(response.body().string());}
Post方式提交分块请求
private static final String IMGUR_CLIENT_ID = "...";private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");private final OkHttpClient client = new OkHttpClient();public void run() throws Exception { //MultipartBuilder可以构建复杂的请求体,与HTML文件上传形式兼容。 //多块请求体中每块请求都是一个请求体,可以定义自己的请求头。 //这些请求头可以用来描述这块请求,例如他的Content-Disposition。 //如果Content-Length和Content-Type可用的话,他们会被自动添加到请求头中。 RequestBody requestBody = new MultipartBuilder() .type(MultipartBuilder.FORM) .addPart( Headers.of("Content-Disposition", "form-data; name=\"title\""), RequestBody.create(null, "Square Logo")) .addPart( Headers.of("Content-Disposition", "form-data; name=\"image\""), RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png"))) .build(); Request request = new Request.Builder() .header("Authorization", "Client-ID " + IMGUR_CLIENT_ID) .url("https://api.imgur.com/3/image") .post(requestBody) .build(); Response response = client.newCall(request).execute(); if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); System.out.println(response.body().string());}
异步上传Multipart文件
private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");private void sendMultipart(){ mOkHttpClient = new OkHttpClient(); RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("title", "wangshu") .addFormDataPart("image", "wangshu.jpg", RequestBody.create(MEDIA_TYPE_PNG, new File("/sdcard/wangshu.jpg"))) .build(); Request request = new Request.Builder() .header("Authorization", "Client-ID " + "...") .url("https://api.imgur.com/3/image") .post(requestBody) .build(); mOkHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { Log.i("wangshu", response.body().string()); } });}
使用Gson来解析JSON响应
private final OkHttpClient client = new OkHttpClient();private final Gson gson = new Gson();public void run() throws Exception { Request request = new Request.Builder() .url("https://api.github.com/gists/c2a7c39532239ff261be") .build(); Response response = client.newCall(request).execute(); if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); //ResponseBody.charStream()使用响应头Content-Type指定的字符集来解析响应体。默认是UTF-8。 Gist gist = gson.fromJson(response.body().charStream(), Gist.class); for (Map.Entry<String, GistFile> entry : gist.files.entrySet()) { System.out.println(entry.getKey()); System.out.println(entry.getValue().content); }}static class Gist { Map<String, GistFile> files;}static class GistFile { String content;}
响应缓存:响应缓存使用HTTP头作为配置。你可以在请求头中添加Cache-Control: max-stale=3600 ,OkHttp缓存会支持。你的服务通过响应头确定响应缓存多长时间,例如使用Cache-Control: max-age=9600。
private final OkHttpClient client;public CacheResponse(File cacheDirectory) throws Exception { int cacheSize = 10 * 1024 * 1024; // 10 MiB Cache cache = new Cache(cacheDirectory, cacheSize); client = new OkHttpClient(); client.setCache(cache);}public void run() throws Exception { Request request = new Request.Builder() .url("http://publicobject.com/helloworld.txt") .build(); Response response1 = client.newCall(request).execute(); if (!response1.isSuccessful()) throw new IOException("Unexpected code " + response1); String response1Body = response1.body().string(); System.out.println("Response 1 response: " + response1); System.out.println("Response 1 cache response: " + response1.cacheResponse()); System.out.println("Response 1 network response: " + response1.networkResponse()); Response response2 = client.newCall(request).execute(); if (!response2.isSuccessful()) throw new IOException("Unexpected code " + response2); String response2Body = response2.body().string(); System.out.println("Response 2 response: " + response2); System.out.println("Response 2 cache response: " + response2.cacheResponse()); System.out.println("Response 2 network response: " + response2.networkResponse()); System.out.println("Response 2 equals Response 1? " + response1Body.equals(response2Body));}
缓存
//创建Cache File httpCacheDirectory = new File(MyApp.getContext().getCacheDir(), "OkHttpCache"); Cache cache = new Cache(httpCacheDirectory, 10 * 1024 * 1024); httpClientBuilder.cache(cache); //设置缓存 httpClientBuilder.addNetworkInterceptor(getCacheInterceptor2()); httpClientBuilder.addInterceptor(getCacheInterceptor2());
缓存拦截器
缓存时间自己根据情况设定
/** * 在无网络的情况下读取缓存,有网络的情况下根据缓存的过期时间重新请求, * * @return */ public Interceptor getCacheInterceptor2() { Interceptor commonParams = new Interceptor() { @Override public okhttp3.Response intercept(Chain chain) throws IOException { Request request = chain.request(); if (!NetworkUtils.isConnected()) { //无网络下强制使用缓存,无论缓存是否过期,此时该请求实际上不会被发送出去。 request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build(); } okhttp3.Response response = chain.proceed(request); if (NetworkUtils.isConnected()) { //有网络情况下,根据请求接口的设置,配置缓存。 // 这样在下次请求时,根据缓存决定是否真正发出请求。 String cacheControl = request.cacheControl().toString(); //当然如果你想在有网络的情况下都直接走网络,那么只需要 // 将其超时时间这是为0即可:String cacheControl="Cache-Control:public,max-age=0" int maxAge = 60 * 60; // read from cache for 1 minute return response.newBuilder() .header("Cache-Control", cacheControl).header("Cache-Control", "public, max-age=" + maxAge).removeHeader("Pragma").build(); } else { //无网络 int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale return response.newBuilder() //.header("Cache-Control", "public,only-if-cached,max-stale=360000") .header("Cache-Control", "public,only-if-cached,max-stale=" + maxStale).removeHeader("Pragma").build(); } } }; return commonParams; }}
取消一个Call
使用Call.cancel()可以立即停止掉一个正在执行的call。如果一个线程正在写请求或者读响应,将会引发IOException。当call没有必要的时候,使用这个api可以节约网络资源。例如当用户离开一个应用时。不管同步还是异步的call都可以取消。
你可以通过tags来同时取消多个请求。当你构建一请求时,使用RequestBuilder.tag(tag)来分配一个标签。之后你就可以用OkHttpClient.cancel(tag)来取消所有带有这个tag的call。
每个call的配置
使用OkHttpClient,所有的HTTP Client配置包括代理设置、超时设置、缓存设置。当你需要为单个call改变配置的时候,clone 一个 OkHttpClient。这个api将会返回一个浅拷贝(shallow copy),你可以用来单独自定义。下面的例子中,我们让一个请求是500ms的超时、另一个是3000ms的超时。
private final OkHttpClient client = new OkHttpClient();public void run() throws Exception { Request request = new Request.Builder() .url("http://httpbin.org/delay/1") // This URL is served with a 1 second delay. .build(); try { Response response = client.clone() // Clone to make a customized OkHttp for this request. .setReadTimeout(500, TimeUnit.MILLISECONDS) .newCall(request) .execute(); System.out.println("Response 1 succeeded: " + response); } catch (IOException e) { System.out.println("Response 1 failed: " + e); } try { Response response = client.clone() // Clone to make a customized OkHttp for this request. .setReadTimeout(3000, TimeUnit.MILLISECONDS) .newCall(request) .execute(); System.out.println("Response 2 succeeded: " + response); } catch (IOException e) { System.out.println("Response 2 failed: " + e); }}
拦截器
1)请求头拦截器
/** * 拦截器Interceptors * 使用addHeader()不会覆盖之前设置的header,若使用header()则会覆盖之前的header * * @return */ public static Interceptor getRequestHeader() { Interceptor headerInterceptor = new Interceptor() { @Override public okhttp3.Response intercept(Chain chain) throws IOException { Request originalRequest = chain.request(); Request.Builder builder = originalRequest.newBuilder(); builder.addHeader("version", "1"); builder.addHeader("time", System.currentTimeMillis() + ""); Request.Builder requestBuilder =builder.method(originalRequest.method(), originalRequest.body()); Request request = requestBuilder.build(); return chain.proceed(request); } }; return headerInterceptor; }
2)统一请求拦截器
/** * 拦截器Interceptors * 统一的请求参数 */private Interceptor commonParamsInterceptor() { Interceptor commonParams = new Interceptor() { @Override public okhttp3.Response intercept(Chain chain) throws IOException { Request originRequest = chain.request(); Request request; HttpUrl =httpUrl=originRequest.url().newBuilder().addQueryParameter("paltform", "android").addQueryParameter("version", "1.0.0").build(); request = originRequest.newBuilder().url(httpUrl).build(); return chain.proceed(request); } }; return commonParams; }
3)时间拦截器
/** * 拦截器Interceptors * 通过响应拦截器实现了从响应中获取服务器返回的time * * @return */ public static Interceptor getResponseHeader() { Interceptor interceptor = new Interceptor() { @Override public okhttp3.Response intercept(Chain chain) throws IOException { okhttp3.Response response = chain.proceed(chain.request()); String timestamp = response.header("time"); if (timestamp != null) { //获取到响应header中的time } return response; } }; return interceptor; }
- okhttp3使用
- okhttp3使用
- okhttp3使用
- okhttp3使用
- okhttp3的简单使用
- 浅析 - okHttp3使用总结
- okhttp3的使用
- Retrofit2+okhttp3 使用教程
- OkHttp3使用详解
- OkHttp3使用详解
- OkHttp3 如何使用
- OkHttp3的使用
- okhttp3使用详解
- OkHttp3使用详解
- Android OKhttp3使用
- okhttp3使用总结
- Retrofit2、okHttp3、RxAndroid使用
- okHttp3的简单使用
- vim跳转命令
- vim ctags and quickfix
- Ubuntu 16.04 RTL8111/8168/8411 不能上网 经常断网解决办法 Author 时鹏亮 | 11/18/2016 = =这奇葩情况发生在从14.04升级到16.04之后,开始以
- Factory and Decorator (工厂模式与装饰者模式)
- 内存溢出的多种原因及优化方法
- okhttp3使用
- 网络安全法与LogSec日志安全大数据审计平台
- LogSec金融行业营业厅终端安全解决方案
- 渗透测试工具(sqlmap)
- 威胁情报助力SIEM平台识别安全威胁
- Java内存溢出和内存泄露
- swiper-滑块视图容器
- 第一天,介绍一下自己吧
- MySQL存储引擎总结