一. 前言 1. 关于本地服务器 我的选择是使用自己的电脑作为服务器。我们的手机该如何才能访问的电脑呢?
首先,我们需要将我们的手机和电脑连接在同一个局域网下,手机开热点给电脑连接也可以。
接着,我们需要在终端输入 ifconfig
,回车,找到 inet
,后面的一串数字就是我们本机的ip地址(ip地址可能变动),比如我的电脑此时的ip就是:192.168.43.43。
2. 操作本地服务器
前往本地服务器的文件夹:/Library/WebServer/Documents
,在其中配置我们的后台文件。
我们电脑访问本地服务器的方式是:http://localhost/hello
在手机上我们对应的访问方式是:http://192.168.43.43/hello
3. 实际操作可能出现的问题 程序报错:CLEARTEXT communication to XX not permitted by network security policy
我的第一想法是将 http请求
换成 https请求
,但是发现就不能在手机上访问我电脑上的服务器了。
百度得到结果:安卓9.0系统出现 CLEARTEXT communication to XX not permitted by network security policy
解决步骤:
1 2 3 4 5 6 7 8 9 10 11 <?xml version="1.0" encoding="utf-8" ?> <network-security-config> <base-config cleartextTrafficPermitted="true" /> </network-security-config> <application **** android:networkSecurityConfig="@xml/network_config" ****>
4. 记得在 AndroidManifest.xml 中配置允许联网的权限 1 2 <uses-permission android:name ="android.permission.INTERNET" />
二. Get请求 1. 配置后台文件 在电脑上的服务器文件夹中创建loginGet.php,填入下面的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <?PHP $name = $_GET ["name" ]; $pwd = $_GET ["password" ]; $account = array ( "name" =>$name , "password" =>$pwd , ); $result = array ( "account" =>$account , "id" =>"222017602053039" , "status" =>3 , ); header('Content-Type:application/json' ); echo json_encode($result ); ?>
2. 使用Postman查询请求 ① 请求头
② 请求体
3. 发送同步Get请求获取数据 ① 使用
同步Get请求会阻塞主线程,需要开启子线程调用。
使用GsonFormat插件生成模型类。
使用Gson第三方库解析JSON数据。
② 代码解释
client执行newCall方法会得到一个Call对象,表示一个新的网络请求。Call对象的execute方法是同步方法,会阻塞当前线程,其返回Response对象。
通过Response对象的isSuccessful()方法可以判断请求是否成功。
通过Response的headers()方法可以得到响应头Headers对象,可以通过for循环索引遍历所有的响应头的名称和值。可以通过Headers.name(index)方法获取响应头的名称,通过Headers.value(index)方法获取响应头的值。
除了索引遍历,通过Headers.get(headerName)方法也可以获取某个响应头的值,比如通过headers.get(“Content-Type”)获得服务器返回给客户端的数据类型。
但是服务器返回给客户端的响应头中有可能有多个重复名称的响应头,比如在某个请求中,服务器要向客户端设置多个Cookie,那么会写入多个Set-Cookie响应头,且这些Set-Cookie响应头的值是不同的,例如访问百度首页,就有3个Set-Cookie响应头。
为了解决同时获取多个name相同的响应头的值,Headers中提供了一个public List values(String name)方法,该方法会返回一个List对象,所以此处通过Headers对象的values(‘Set-Cookie’)可以获取全部的Cookie信息,如果调用Headers对象的get(‘Set-Cookie’)方法,那么只会获取最后一条Cookie信息。
通过Response对象的body()方法可以得到响应体ResponseBody对象,调用其string()方法可以很方便地将响应体中的数据转换为字符串,该方法会将所有的数据放入到内存之中,所以如果数据超过1M,最好不要调用string()方法以避免占用过多内存,这种情况下可以考虑将数据当做Stream流处理。
③ 代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 public class MainActivity extends AppCompatActivity { public static final String TAG = MainActivity.class.getSimpleName(); private final OkHttpClient client = new OkHttpClient(); @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); new Thread(new Runnable() { @Override public void run () { syncRequestByGet(); } }).start(); } public void syncRequestByGet () { Request.Builder builder = new Request.Builder(); builder.url("http://192.168.43.43/login/loginGet?name=xl&password=0000" ); Request request = builder.build(); try { Response response = client.newCall(request).execute(); if (response.isSuccessful()) { ResponseBody body = response.body(); String jsonString = body.string(); Gson gson = new Gson(); Student student = gson.fromJson(jsonString, Student.class); Log.d(TAG,student.toString()); }else { Log.d(TAG,"响应失败" ); } } catch (IOException e) { e.printStackTrace(); Log.d(TAG,"IO异常:" +e.getMessage()); } } } Date:Mon, 01 Jun 2020 08:25 :24 GMT Server:Apache/2.4 .41 (Unix) PHP/7.3 .11 Content-Location:loginGet.php Vary:negotiate TCN:choice X-Powered-By:PHP/7.3 .11 Content-Length:77 Keep-Alive:timeout=5 , max=100 Connection:Keep-Alive Content-Type:application/json Student{account=AccountBean{name='xl' , password='0000' }, id='222017602053039' , status=3 }
4. 发送异步Get请求 ① 代码解释
要想异步执行网络请求,需要执行Call对象的enqueue方法,该方法接收一个okhttp3.Callback对象,enqueue方法不会阻塞当前线程,会新开一个工作线程,让实际的网络请求在工作线程中执行。
当异步请求成功后,会回调Callback对象的onResponse方法,在该方法中可以获取Response对象。当异步请求失败或者调用了Call对象的cancel方法时,会回调Callback对象的onFailure方法。onResponse和onFailure这两个方法都是在工作线程中执行的。
② 代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 public class MainActivity extends AppCompatActivity { public static final String TAG = MainActivity.class.getSimpleName(); private final OkHttpClient client = new OkHttpClient(); @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); asyncRequestByGet(); } public void asyncRequestByGet () { Request.Builder builder = new Request.Builder(); builder.url("http://192.168.43.43/login/loginGet?name=xl&password=0000" ); Request request = builder.build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure (@NotNull Call call, @NotNull IOException e) { Log.d(TAG,"响应失败" ); } @Override public void onResponse (@NotNull Call call, @NotNull Response response) throws IOException { if (response.isSuccessful()) { Headers headers = response.headers(); for (int i = 0 ; i < headers.size(); i++) { Log.d(TAG,headers.name(i)+":" +headers.value(i)); } ResponseBody body = response.body(); String jsonString = body.string(); Gson gson = new Gson(); Student student = gson.fromJson(jsonString, Student.class); Log.d(TAG,student.toString()); }else { Log.d(TAG,"响应失败" ); } } }); } } Date:Mon, 01 Jun 2020 08:25 :24 GMT Server:Apache/2.4 .41 (Unix) PHP/7.3 .11 Content-Location:loginGet.php Vary:negotiate TCN:choice X-Powered-By:PHP/7.3 .11 Content-Length:77 Keep-Alive:timeout=5 , max=100 Connection:Keep-Alive Content-Type:application/json Student{account=AccountBean{name='xl' , password='0000' }, id='222017602053039' , status=3 }
5. 请求头和响应头 典型的HTTP请求头、响应头都是类似于Map<String, String>,每个name对应一个value值。不过像我们之前提到的,也会存在多个name重复的情况,比如相应结果中就有可能存在多个Set-Cookie响应头,同样的,也可能同时存在多个名称一样的请求头。
响应头的读取,我们在上面发送同步Get请求的时候就已经说过了,那么我们如何设置请求头呢?
一般情况下,我们只需要调用header(name, value)方法就可以设置请求头的name和value,调用该方法会确保整个请求头中不会存在多个名称一样的name。如果想添加多个name相同的请求头,应该调用addHeader(name, value)方法,这样可以添加重复name的请求头,其value可以不同,例如如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 private final OkHttpClient client = new OkHttpClient();public void run () { 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(); System.out.println("Server: " + response.header("Server" )); System.out.println("Date: " + response.header("Date" )); System.out.println("Vary: " + response.headers("Vary" )); }
上面的代码通过addHeader方法添加了两个Accept请求头,且二者的值不同,这样服务器收到客户端发来的请求后,就知道客户端既支持application/json类型的数据,也支持application/vnd.github.v3+json类型的数据。
三. 发送POST请求获取数据 1. 配置后台文件 在电脑上的服务器文件夹中创建loginGet.php,填入下面的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <?PHP $name = $_POST ["name" ]; $pwd = $_POST ["password" ]; $account = array ( "name" =>$name , "password" =>$pwd , ); $result = array ( "account" =>$account , "id" =>"222017602053039" , "status" =>3 , ); header('Content-Type:application/json' ); echo json_encode($result ); ?>
2. 使用Postman查询请求 ① 请求头
② 请求体
3. 发送POST请求获取数据 ① 代码解释
POST请求无法向GET请求一样直接在URL后面追加键值对信息。
我们通过在请求的Body中加入form-data类型的信息,达到追加信息的效果。
② 代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 public class MainActivity extends AppCompatActivity { public static final String TAG = MainActivity.class.getSimpleName(); private final OkHttpClient client = new OkHttpClient(); @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); requestByPost(); } private void requestByPost () { Request.Builder builder = new Request.Builder(); FormBody formBody = new FormBody.Builder() .add("username" , "xl" ) .add("password" , "0000" ) .build(); builder.url("http://192.168.43.43/login/loginGet" ); builder.post(formBody); Request request = builder.build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure (@NotNull Call call, @NotNull IOException e) { Log.d(TAG,"响应失败" ); } @Override public void onResponse (@NotNull Call call, @NotNull Response response) throws IOException { if (response.isSuccessful()) { Headers headers = response.headers(); for (int i = 0 ; i < headers.size(); i++) { Log.d(TAG,headers.name(i)+":" +headers.value(i)); } ResponseBody body = response.body(); String jsonString = body.string(); Gson gson = new Gson(); Student student = gson.fromJson(jsonString, Student.class); Log.d(TAG,student.toString()); }else { Log.d(TAG,"响应失败" ); } } }); } } Date:Mon, 01 Jun 2020 09:09:04 GMT Server:Apache/2.4 .41 (Unix) PHP/7.3 .11 X-Powered-By:PHP/7.3 .11 Content-Length:77 Keep-Alive:timeout=5 , max=100 Connection:Keep-Alive Content-Type:application/json Student{account=AccountBean{name='xl' , password='0000' }, id='222017602053039' , status=3 }
4. 用POST发送表单数据
Okhttp也提供了MultipartBody类帮助我们完成这个功能。
MultipartBody继承自RequestBody,也表示请求体。只不过MultipartBody的内部是由多个part组成的,每个part就单独包含了一个RequestBody请求体,所以可以把MultipartBody看成是一个RequestBody的数组,而且可以分别给每个RequestBody单独设置请求头。
MultipartBody一定要设置setType(MultipartBody.FORM)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 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 { RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("title" , "Square Logo" ) .addFormDataPart("image" , "logo-square.png" , 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(); System.out.println(response.body().string()); }
四. 发送POST请求上传文件并获取数据 1. 配置后台文件 在电脑上的服务器文件夹中创建upLoad文件夹以及它下面的file,img,video文件夹,upLoadFile.php文件,并填入下面的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 <?PHP $file = $_FILES ["file" ]; if ($file ["error" ] > 0 ){ echo "Error:" .$file ["error" ]."\n" ; }else { echo "上传的文件名:" .$file ["name" ]."\n" ; echo "上传的文件类型:" .$file ["type" ]."\n" ; echo "上传的文件大小:" .($file ["size" ]/1024 )."Kb\n" ; echo "临时路径:" .$file ["tmp_name" ]."\n" ; $type = $file ["type" ]; $path ; if ($type == "image/jpeg" || $type == "image/png" ){ $path = "upLoad/img/" ; }else if ($type == "video/mp4" ){ $path = "upLoad/video/" ; }else if ($type == "text/plain" ){ $path = "upLoad/file/" ; } } $filePath = $path .$file ["name" ]; if (file_exists($filePath )){ echo $file ["name" ]."已存在" ; }else { move_uploaded_file($file ["tmp_name" ],$filePath ); echo "文件已保存在:" .$filePath ; } ?>
2. 使用Postman查询请求 ① 上传文本
② 上传图片
③ 上传视频
4. 代码 ① 上传文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 private void uploadTextToServer () { final MediaType MEDIA_TYPE = MediaType.parse("text/plain; charset=utf-8" ); final InputStream is = getResources().openRawResource(R.raw.test); RequestBody text_request = new RequestBody() { @Nullable @Override public MediaType contentType () { return MEDIA_TYPE; } @Override public void writeTo (@NotNull BufferedSink bufferedSink) throws IOException { bufferedSink.write(getBytesByInputStream(is)); } }; MultipartBody.Builder multi_builder = new MultipartBody.Builder(); multi_builder.setType(MultipartBody.FORM); multi_builder.addFormDataPart("file" ,"test.txt" ,text_request); RequestBody requestBody = multi_builder.build(); Request.Builder builder = new Request.Builder(); builder.url("http://192.168.43.43/upLoadFile" ); builder.post(requestBody); Request request = builder.build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure (@NotNull Call call, @NotNull IOException e) { Log.d(TAG,"响应失败" ); } @Override public void onResponse (@NotNull Call call, @NotNull Response response) throws IOException { if (response.isSuccessful()) { Headers headers = response.headers(); for (int i = 0 ; i < headers.size(); i++) { Log.d(TAG,headers.name(i)+":" +headers.value(i)); } ResponseBody body = response.body(); String jsonString = body.string(); Log.d(TAG,jsonString); }else { Log.d(TAG,"响应失败" ); } } }); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 Date:Mon, 01 Jun 2020 11 :35 :06 GMT Server:Apache/2.4 .41 (Unix) PHP/7.3 .11 X-Powered-By:PHP/7.3 .11 Content-Length:173 Keep-Alive:timeout=5 , max=100 Connection:Keep-Alive Content-Type:text/html; charset=UTF-8 上传的文件名:test.txt 上传的文件类型:text/plain 上传的文件大小:0. 046875Kb 临时路径:/private /var /tmp/phplJlVE7 文件已保存在:upLoad/file/test.txt
② 上传图片
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 private void uploadPictureToServer () { final MediaType MEDIA_TYPE = MediaType.parse("image/png" ); final InputStream is = getResources().openRawResource(R.raw.test_picture); RequestBody picture_request = new RequestBody() { @Nullable @Override public MediaType contentType () { return MEDIA_TYPE; } @Override public void writeTo (@NotNull BufferedSink bufferedSink) throws IOException { bufferedSink.write(getBytesByInputStream(is)); } }; MultipartBody.Builder multi_builder = new MultipartBody.Builder(); multi_builder.setType(MultipartBody.FORM); multi_builder.addFormDataPart("file" ,"test.png" ,picture_request); RequestBody requestBody = multi_builder.build(); Request.Builder builder = new Request.Builder(); builder.url("http://192.168.43.43/upLoadFile" ); builder.post(requestBody); Request request = builder.build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure (@NotNull Call call, @NotNull IOException e) { Log.d(TAG,"响应失败" ); } @Override public void onResponse (@NotNull Call call, @NotNull Response response) throws IOException { if (response.isSuccessful()) { Headers headers = response.headers(); for (int i = 0 ; i < headers.size(); i++) { Log.d(TAG,headers.name(i)+":" +headers.value(i)); } ResponseBody body = response.body(); String jsonString = body.string(); Log.d(TAG,jsonString); }else { Log.d(TAG,"响应失败" ); } } }); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 Date:Mon, 01 Jun 2020 12 :49 :54 GMT Server:Apache/2.4 .41 (Unix) PHP/7.3 .11 X-Powered-By:PHP/7.3 .11 Content-Length:177 Keep-Alive:timeout=5 , max=100 Connection:Keep-Alive Content-Type:text/html; charset=UTF-8 上传的文件名:test.png 上传的文件类型:image/png 上传的文件大小:670. 1064453125Kb 临时路径:/private /var /tmp/phpAblC1W 文件已保存在:upLoad/img/test.png
③ 上传视频
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 private void uploadMovieToServer () { final MediaType MEDIA_TYPE = MediaType.parse("video/mp4; charset=utf-8" ); final InputStream is = getResources().openRawResource(R.raw.test_movie); RequestBody movie_request = new RequestBody() { @Nullable @Override public MediaType contentType () { return MEDIA_TYPE; } @Override public void writeTo (@NotNull BufferedSink bufferedSink) throws IOException { bufferedSink.write(getBytesByInputStream(is)); } }; MultipartBody.Builder multi_builder = new MultipartBody.Builder(); multi_builder.setType(MultipartBody.FORM); multi_builder.addFormDataPart("file" ,"test.mp4" ,movie_request); RequestBody requestBody = multi_builder.build(); Request.Builder builder = new Request.Builder(); builder.url("http://192.168.43.43/upLoadFile" ); builder.post(requestBody); Request request = builder.build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure (@NotNull Call call, @NotNull IOException e) { Log.d(TAG,"响应失败" ); } @Override public void onResponse (@NotNull Call call, @NotNull Response response) throws IOException { if (response.isSuccessful()) { Headers headers = response.headers(); for (int i = 0 ; i < headers.size(); i++) { Log.d(TAG,headers.name(i)+":" +headers.value(i)); } ResponseBody body = response.body(); String jsonString = body.string(); Log.d(TAG,jsonString); }else { Log.d(TAG,"响应失败" ); } } }); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 Date:Tue, 02 Jun 2020 02 :13 :29 GMT Server:Apache/2.4 .41 (Unix) PHP/7.3 .11 X-Powered-By:PHP/7.3 .11 Content-Length:180 Keep-Alive:timeout=5 , max=100 Connection:Keep-Alive Content-Type:text/html; charset=UTF-8 上传的文件名:test.mp4 上传的文件类型:video/mp4 上传的文件大小:20221. 448242188Kb 临时路径:/private /var /tmp/phpI5C1uB 文件已保存在:upLoad/video/test.mp4
④ 辅助函数:将输入流->字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 private byte [] getBytesByInputStream(InputStream is) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte [] data = new byte [1024 ]; int len; try { while ((len = is.read(data)) != -1 ){ bos.write(data,0 ,len); } bos.flush(); bos.close(); } catch (IOException e) { e.printStackTrace(); } return bos.toByteArray(); }
5. 关于上传视频的一点小问题 ① Error:1 错误
② PHP上传错误类型
假设文件上传字段的名称file,则$_FILES['file']['error']
有以下几种错误类型:
UPLOAD_ERR_OK:其值为 0,没有错误发生,文件上传成功。
UPLOAD_ERR_INI_SIZE:其值为 1,上传的文件超过了 php.ini 中 upload_max_filesize选项限制的值。
UPLOAD_ERR_FORM_SIZE:其值为 2,上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值。
UPLOAD_ERR_PARTIAL:其值为 3,文件只有部分被上传。
UPLOAD_ERR_NO_FILE:其值为 4,没有文件被上传。
UPLOAD_ERR_NO_TMP_DIR:其值为 6,找不到临时文件夹。PHP 4.3.10 和 PHP 5.0.3 引进。
UPLOAD_ERR_CANT_WRITE:其值为 7,文件写入失败。PHP 5.1.0 引进。
③ 改正方式
修改:php.ini 中 upload_max_filesize 选项限制的值。
问题1:Mac OS X中没有默认的php.ini文件
使用对应的模版文件php.ini.default,修改upload_max_filesize,然后执行以下的拷贝命令即可。
1 sudo cp /private /etc/php.ini.default /private /etc/php.ini
问题2:仍然不成功的情况
php默认的 post_max_size 为 2M。如果 POST 数据尺寸大于 post_max_size,页面不会给出提醒,文件也上传失败 。
按照问题1的方式修改 post_max_size。
五. 发送GET请求下载图片 1. 使用Postman查询请求
2. 代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 private void downloadPicture () { Request.Builder builder = new Request.Builder(); builder.url("http://192.168.43.43/upLoad/img/test.png" ); Request request = builder.build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure (@NotNull Call call, @NotNull IOException e) { Log.d(TAG,"响应失败" ); } @Override public void onResponse (@NotNull Call call, @NotNull Response response) throws IOException { if (response.isSuccessful()) { Headers headers = response.headers(); for (int i = 0 ; i < headers.size(); i++) { Log.d(TAG,headers.name(i)+":" +headers.value(i)); } ResponseBody body = response.body(); InputStream is = body.byteStream(); final Bitmap bitmap = BitmapFactory.decodeStream(is); runOnUiThread(new Runnable() { @Override public void run () { imageView.setImageBitmap(bitmap); } }); is.close(); }else { Log.d(TAG,"响应失败" ); } } }); }
六. 源码 OkHttpTest
参考文章 界面提交方式-Get和Post
上传和下载视频到本地服务器
文加图, 理解Http请求与响应
OkHttp使用详解
Android 网络(三) HttpURLConnection OkHttp
修改php文件上传的大小限制upload_max_filesize
PHP使用之修改php.ini 配置文件(Mac)