AndroidStudio引入okHttp3
implementation files('libs/okio-1.14.1.jar')
implementation files('libs/okhttp-3.10.0.jar')
//-----------------------------引入最新的版本号
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
下载jar包
链接:https://pan.baidu.com/s/1M4vcDRQCFMl8HgawXss0gA 密码:nz04
上传文件
//以二进制的形式上传文件
public static final MediaType MEDIA_TYPE_STREAM = MediaType.parse("application/octet-stream");
private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
/**
* 多文件上传---Map<String, String> maps表示请求头参数
* <br/><br/>
* 文件流形式
* <br/><br/>
* 暂定传入png格式的图片
*/
public static final void postAsyncmultiFile(OkHttpClient okHttpClient, String url,
List<File> files, Map<String, String> maps,
Callback callback) {
MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);//传输类型
if (maps == null) {
for (int i = 0; i < files.size(); i++) {
QZXTools.logD("zbv", "file name="+files.get(i).getName());
if (files.get(i).getName().contains(".png") || files.get(i).getName().contains(".jpg")
|| files.get(i).getName().contains(".gif")) {
builder.addPart(Headers.of("Content-Disposition",
"form-data; name=\"file\";filename=\"file.png\""),
RequestBody.create(MEDIA_TYPE_PNG, files.get(i))
).build();
} else {
builder.addPart(Headers.of("Content-Disposition",
"form-data; name=\"file\";filename=\"" + files.get(i).getName() + "\""),
RequestBody.create(MEDIA_TYPE_STREAM, files.get(i))
).build();
}
}
} else {
for (String key : maps.keySet()) {
String str = maps.get(key);
builder.addFormDataPart(key, str);
}
for (int j = 0; j < files.size(); j++) {
long fileSize = files.get(j).length();
QZXTools.logD("zbv", "file name="+files.get(j).getName());
if (files.get(j).getName().contains(".png") || files.get(j).getName().contains(".jpg")
|| files.get(j).getName().contains(".gif")) {
builder.addPart(Headers.of("Content-Disposition",
"form-data; name=\"file\";filename=\"file.png\";filesize=" + fileSize),
RequestBody.create(MEDIA_TYPE_PNG, files.get(j))
);
} else {
builder.addPart(Headers.of("Content-Disposition",
"form-data; name=\"file\";filename=\"" + files.get(j).getName()
+ "\";filesize=" + fileSize),
RequestBody.create(MEDIA_TYPE_STREAM, files.get(j))
);
}
}
}
RequestBody requestBody = builder.build();
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
okHttpClient.newCall(request).enqueue(callback);
}
Post请求
/**
* okHttp---post模式enqueue---异步模式
*/
public static void postokHttpAsync(OkHttpClient okHttpClient, String url, Map<String, String> paraMap, Callback callback) {
//FormEncodingBuilder---在okHttp3中没有该类用FormBody替代
// RequestBody body=new FormBody.Builder().add("","").build();
FormBody.Builder builder = new FormBody.Builder();
//HashMap的遍历
Iterator iterator = paraMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = (Map.Entry<String, String>) iterator.next();
// logD("zbv", "key=" + entry.getKey() + ";value=" + entry.getValue());
builder.add(entry.getKey(), entry.getValue());
}
RequestBody requestBody = builder.build();
Request request = new Request.Builder().url(url).post(requestBody).build();
Call call = okHttpClient.newCall(request);
call.enqueue(callback);
}
GET请求—同步和异步
/**
* okHttp---get模式enqueue---异步模式
* 如果需要下载文件的话,结果返回使用response.body().byteStream();
*/
public static void getokHttpAsync(OkHttpClient okHttpClient, String url, Callback callback) {
Request request = new Request.Builder().url(url).build();
Call call = okHttpClient.newCall(request);
call.enqueue(callback);
}
/**
* okHttp---get模式execute---同步模式
*/
public static String getokHttpSync(OkHttpClient okHttpClient, String url) {
Request request = new Request.Builder().url(url).build();
//同样的取消网络请求可以使用->call.cancel();
Call call = okHttpClient.newCall(request);
Response response = null;
try {
response = call.execute();
if (response.isSuccessful()) {
String result = response.body().string();
logD("zbv", "getokHttpSync result json=" + result);
return result;
}
} catch (IOException e) {
e.printStackTrace();
logD("zbv", "getokHttpSync result code=" + response.code());
}
return null;
}
拓展post
//----------------------------------------------------------------
public static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8");
/**
* 以json格式上传参数
* <br/><br/>
* 通过create创建requestbody
*/
public static void postAsyncJson(OkHttpClient okHttpClient, String url, String json, Callback callback) {
RequestBody requestBody = RequestBody.create(MEDIA_TYPE_JSON, json);
Request request = new Request.Builder().url(url).post(requestBody).build();
Call call = okHttpClient.newCall(request);
call.enqueue(callback);
}
/**
* 上传单个文件,格式是流,传入的是文件file
* <br/><br/>
* 通过create创建requestbody
*/
public static void postSingleFile(OkHttpClient okHttpClient, String url, File file, Callback callback) {
RequestBody requestBody = RequestBody.create(MEDIA_TYPE_STREAM, file);
Request request = new Request.Builder().url(url).post(requestBody).build();
Call call = okHttpClient.newCall(request);
call.enqueue(callback);
}
//----------------------------------------------------------------
设置超时以及缓存(2.0和3.0有差异)
// 响应缓存
// public CacheResponse(File cacheDirectory) throws Exception {
// int cacheSize = 10 * 1024 * 1024; // 10 MiB
// Cache cache = new Cache(cacheDirectory, cacheSize);
//
// client = new OkHttpClient();
//设置超时和缓存okHttp3.0
// File sdcache = getExternalCacheDir();
// int cacheSize = 10 * 1024 * 1024;
// OkHttpClient.Builder builder = new OkHttpClient.Builder()
// .connectTimeout(15, TimeUnit.SECONDS)
// .writeTimeout(20, TimeUnit.SECONDS)
// .readTimeout(20, TimeUnit.SECONDS)
// .cache(new Cache(sdcache.getAbsoluteFile(), cacheSize));
// OkHttpClient mOkHttpClient=builder.build();
//设置超时和缓存okhttp2.0
// client.setConnectTimeout(10, TimeUnit.SECONDS);
// client.setWriteTimeout(10, TimeUnit.SECONDS);
// client.setReadTimeout(30, TimeUnit.SECONDS);
// client.setCache(cache);
使用实例
// 上传文件流给服务器
private void uploadServer(String path) {
File file = new File(path);
if (file != null && file.exists()) {
UtilityClass.logD("zbv", "所需文件存在" + path);
OkHttpClient okHttpClient = new OkHttpClient();
String url = "http://" + ConstantClass.getIP(getContext()) + ":" + ConstantClass.getPort(getContext())
+ "/Home/FileSave";
LinkedHashMap<String, String> paraMap = new LinkedHashMap<>();
paraMap.put("MeetingId", ConstantClass.getMeetingID(getContext()));
paraMap.put("UserName", ConstantClass.getLoginName(getContext()));
ArrayList<File> files = new ArrayList<>();
files.add(file);
UtilityClass.postAsyncmultiFile(okHttpClient, url, files, paraMap, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
UtilityClass.logD("zbv", "MeetingFileFragment onFailure");
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getContext(), "上传失败,请检查网络",
Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String resultJson = response.body().string();
UtilityClass.logD("zbv", "resultJson=" + resultJson);
try {
JSONObject jsonObject = new JSONObject(resultJson);
int result = jsonObject.getInt("Flag");
String meg = jsonObject.getString("Message");
if (result == 1 && meg.contains("成功")) {
UtilityClass.logD("zbv", "上传成功");
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getContext(), "上传成功",
Toast.LENGTH_SHORT).show();
}
});
} else if (result == 0) {
UtilityClass.logD("zbv", "上传失败");
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getContext(), "上传失败",
Toast.LENGTH_SHORT).show();
}
});
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
} else {
UtilityClass.logD("zbv", "所需文件不存在" + path);
}
}
Retrofit框架
一、引入依赖
// Retrofit库
compile 'com.squareup.retrofit2:retrofit:2.0.2'
// Okhttp库
compile 'com.squareup.okhttp3:okhttp:3.1.2'
//gson依赖针对retrofit的数据解析
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
二、构建服务器返回的实体类,也可以不需要一般按照Gson格式制定即可
三、网络请求接口编写(例如)
package com.example.demo_test_http;
import com.example.demo_test_http.gson_entities.AllSignInfo;
import com.example.demo_test_http.gson_entities.LoginSuccessInfo;
import com.example.demo_test_http.gson_entities.SelectMeetingSignInfo;
import java.util.List;
import java.util.Map;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Field;
import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;
import retrofit2.http.PartMap;
import retrofit2.http.Path;
import retrofit2.http.Query;
import retrofit2.http.Streaming;
/**
* Retrofit网络请求接口
*/
public interface URLRequetInterface {
/*
* POST请求,@Field和@FormUrlEncoded配合使用的表单传递数据的形式
*/
@POST("/Home/Login")
@FormUrlEncoded
Call<ResponseBody> getLoginInfoCall(@Field("loginName") String loginName, @Field("pwd") String pwd);
@POST("/Home/Login")
@FormUrlEncoded
Call<LoginSuccessInfo> getLoginInfoCall(@FieldMap Map<String, String> paraMap);
/*
*/
@POST("/Home/MeetingSignIn")
@FormUrlEncoded
Call<SelectMeetingSignInfo> getSelectSignInfoCall(@Field("data") String jsonData);
/*
* 熟练@Path的省缺填补以及@Query的?后面的参数设置
*/
@GET("/Home/{aim}")
Call<AllSignInfo> getAllSignedInfoCall(@Path("aim") String aim, @Query("meetingId") int meetingId);
/*
* 下载大文件
* <br/>
* /UploadFile/2018-07-12/0f435d58-0be7-4e00-b9c9-8bb24016d4e1.txt
*/
@Streaming
@GET("{filePath}")
Call<ResponseBody> downloadBigFileCall(@Path("filePath") String filePath);
/*
* 文件的上传---带其他参数的
* <br/>
* http://172.16.4.43:8090/Home/FileSave MeetingId=7、UserName="admin"以及
*/
@POST("/Home/FileSave")
@Multipart
Call<ResponseBody> uploadFileCall(@PartMap Map<String, RequestBody> paraMap, @Part MultipartBody.Part file);
@POST("/Home/FileSave")
@Multipart
Call<ResponseBody> uploadFileCall(@Part("MeetingId") int meetingId, @Part("UserName") String userName,
@Part MultipartBody.Part file);
//多文件上传---一
@POST("/Home/FileSave")
@Multipart
Call<ResponseBody> uploadFileCall(@Part("MeetingId") int meetingId, @Part("UserName") String userName,
@Part List<MultipartBody.Part> fileList);
//多文件上传---二
@POST("/Home/FileSava")
Call<ResponseBody> uploadFileCall2(@Body MultipartBody multipartBody);
}
之后的几步如代码所示
//第四步:创建Retrofit---使用原生的CallAdapter
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://172.16.4.43:8090")
.addConverterFactory(GsonConverterFactory.create())
.build();
//第五步:创建请求接口
URLRequetInterface requetInterface = retrofit.create(URLRequetInterface.class);
//第六步:获取Call
MediaType textType = MediaType.parse("text/plain");
RequestBody meetingId = RequestBody.create(textType, "7");
RequestBody userName = RequestBody.create(textType, "admin");
MediaType fileType = MediaType.parse("application/octet-stream");
//以字符串文本作为文件
RequestBody file = RequestBody.create(fileType, "hello world");
LinkedHashMap<String, RequestBody> paraMap = new LinkedHashMap<>();
paraMap.put("MeetingId", meetingId);
paraMap.put("UserName", userName);
String fileName = "";
try {
fileName = URLEncoder.encode("接口地址.txt", "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//这一步处理是标志为文件的,包含在Content-Disposition请求头中
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", fileName, file);
//上传单个文件
Call<ResponseBody> call = requetInterface.uploadFileCall(7, "admin", filePart);
// Call<ResponseBody> call = requetInterface.uploadFileCall(paraMap, filePart);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
String resultJson = response.body().string();
showTv.setText(resultJson);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(MainActivity.this, "onFailure", Toast.LENGTH_SHORT).show();
}
});
//Get模式的缺省拼接访问,完全可以用Post方式
// Call<AllSignInfo> call = requetInterface.getAllSignedInfoCall("GetMeetingSignList", 7);
// call.enqueue(new Callback<AllSignInfo>() {
// @Override
// public void onResponse(Call<AllSignInfo> call, Response<AllSignInfo> response) {
// showTv.setText(response.body().toString());
// }
//
// @Override
// public void onFailure(Call<AllSignInfo> call, Throwable t) {
//
// }
// });
// JSONObject jsonObject = new JSONObject();
// try {
// jsonObject.put("MeetingId", 7);
// jsonObject.put("UserId", 4);
// jsonObject.put("UserName", "admin");
// jsonObject.put("SignTime", QZXTools.getFormatCurrentDateToSecond());
// } catch (JSONException e) {
// e.printStackTrace();
// }
//
// QZXTools.logD("zbv", "json=" + jsonObject.toString());
//
// Call<SelectMeetingSignInfo> call = requetInterface.getSelectSignInfoCall(jsonObject.toString());
//
// call.enqueue(new Callback<SelectMeetingSignInfo>() {
// @Override
// public void onResponse(Call<SelectMeetingSignInfo> call, Response<SelectMeetingSignInfo> response) {
//
// showTv.setText(response.body().toString());
// }
//
// @Override
// public void onFailure(Call<SelectMeetingSignInfo> call, Throwable t) {
// Toast.makeText(MainActivity.this, "onFailure", Toast.LENGTH_SHORT).show();
// }
// });
//Call中是ResponseBody对象
// Call<ResponseBody> call = requetInterface.getLoginInfoCall("admin", "admin");
// //第七步:异步请求服务
// call.enqueue(new Callback<ResponseBody>() {
// @Override
// public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
// try {
// String result = response.body().string();
// showTv.setText("result=" + result);
// Gson gson = new Gson();
// LoginSuccessInfo loginSuccessInfo = gson.fromJson(result, LoginSuccessInfo.class);
// Log.d("zbv", "loginSuccessInfo=" + loginSuccessInfo);
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
//
// @Override
// public void onFailure(Call<ResponseBody> call, Throwable t) {
//
// }
// });
//Call中是Gson对象
// call.enqueue(new Callback<LoginSuccessInfo>() {
// @Override
// public void onResponse(Call<LoginSuccessInfo> call, Response<LoginSuccessInfo> response) {
//
// showTv.setText(response.body().toString());
//
// }
//
// @Override
// public void onFailure(Call<LoginSuccessInfo> call, Throwable t) {
//
// int result = QZXTools.checkNetworkConnected(MainActivity.this);
//
// Log.e("zbv", "onFailure " + result, t);
//
// Toast.makeText(MainActivity.this, "onFailure", Toast.LENGTH_SHORT).show();
// }
// });
后续更新配合RxJava