在前面一篇文章中,大概介绍了一些关于retrofit的相关用法,但是还是不够具体,下面几篇文章将着重以萌萌哒app的网络请求作为重构。
此篇将介绍登录接口的重构,下面贴上使用阿帕奇的httpclient方法(现谷歌已不提倡使用)
public static String execute(String url, String jsonStr, String filePath,
int conTimeout, int soTimeout) {
// 发送一个post请求并得到返回值,如果其中发生异常,则返回null,
// 如果服务器端正常返回,则对其解码后返回解码的字符串
// 如果filePath不为空,则上传该文件
// conTimeout为连接超时,单位为毫秒,如果为0或负数则用默认值
// soTimeout为TCP超时,单位为毫秒,如果为0或负数,则用默认值
File f1 = new File(Constants.FILECACHE_DIR);
if (!f1.exists()) {
f1.mkdirs();
}
try {
HttpParams httpParams = null; // http参数
HttpClient httpClient = null; // http请求实体
HttpResponse response = null; // http返回实体
String reJsonStr = null; // 服务端返回的json字符串
HttpPost httpPost = null;
MultipartEntity entity = null; // post 参数
int sTimeout = 0; // socket timeout
int cTimeout = 0; // connection timeout
if (conTimeout <= 0) {
cTimeout = Constants.ConnectionTimeout;
} else {
cTimeout = conTimeout;
}
if (soTimeout <= 0) {
sTimeout = Constants.SocketTimeout;
} else {
sTimeout = soTimeout;
}
// 设置http超时参数
httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, cTimeout);// 连接超时
HttpConnectionParams.setSoTimeout(httpParams, sTimeout);// 请求超时
HttpConnectionParams.setSocketBufferSize(httpParams,
Constants.SocketBufferSize);
httpClient = new DefaultHttpClient(httpParams);
entity = new MultipartEntity();
// 解码
String pp = Base64.encodeToString(jsonStr.getBytes(),
Base64.DEFAULT);
StringBody pParmas = null;
Log.e("jiang",jsonStr+"~~~~~~~"+pp);
try {
pParmas = new StringBody(pp);
} catch (UnsupportedEncodingException e) {
if (Constants.TEST)
e.printStackTrace();
}
entity.addPart(Constants.SENDATAP, pParmas); // 添加参数p
if (filePath != null) {
// 添加文件f
FileBody fileBody = new FileBody(new File(filePath));
entity.addPart(Constants.SENDATAF, fileBody); // 添加文件f
}
httpPost = new HttpPost(url);
httpPost.setEntity(entity);
try {
response = httpClient.execute(httpPost);
int code = response.getStatusLine().getStatusCode();
if (code == HttpStatus.SC_OK) {
HttpEntity en = response.getEntity();
String respon = EntityUtils.toString(en);
reJsonStr = new String(
Base64.decode(respon, Base64.DEFAULT));
Log.e("jiang",respon+"~~~~~~~~~~~~"+reJsonStr);
}
JSONObject obj_data = new JSONObject(reJsonStr);
String c = obj_data.getString("c");
if (c.equals("1")) {
}
return reJsonStr;
} catch (ConnectTimeoutException e) {
//连接超时执行什么东西呢 TODO 返回空用来判断获取到的数据
httpClient.getConnectionManager().closeExpiredConnections();
return null;
}
} catch (Exception e) {
return null;
} finally {
}
}
大概逻辑就是以多块 post传递,第一部分参数“p”,第二部分参数“f”,第一部分封装为json数据类型,并转为string进行base64编码,第二部分负责文件发送,此篇不讲。接下来贴出retrofit使用
retrofit
UpXlUser upXlUser = new UpXlUser();
upXlUser.setU("xxxx");
upXlUser.setP("xxxx");
Gson gson = new Gson();
String str = gson.toJson(upXlUser);
String baseStr = Base64.encodeToString(str.getBytes(),
Base64.DEFAULT);
RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain"), baseStr);
Subscription subscription = clientApi.getXlLogin(requestBody)
.compose(SchedulersCompat.<Response>applyIoSchedulers())
.subscribe(new Subscriber<Response>() {
@Override
public void onCompleted() {
hideLoadingDialog();
}
@Override
public void onError(Throwable e) {
showToast("更新失败");
hideLoadingDialog();
}
@Override
public void onNext(Response transDao) {
}
});
需要注意的是,基本信息账号和密码封装成javabean然后利用gson转为json后进行base64编码,然后以text/plain的形式上传。
api接口
@Multipart
@POST("/xl/v2_user_login")
Observable<Response> getXlLogin(@Part("p") RequestBody upTrans);
不懂multipart的可查看这篇文章。
只要是用@MUltipart的注解,则内部一定得用到Part注解,分块请求,如果有多个,可利用PartMap。
service初始化
@Provides
@Singleton
public OkHttpClient provideOkHttpClient(HttpLoggingInterceptor httpLoggingInterceptor,HttpInterceptor httpInterceptor,ProgressInterceptor progressInterceptor) {
OkHttpClient client = new OkHttpClient();
client.setConnectTimeout(10, TimeUnit.SECONDS);
client.setWriteTimeout(10, TimeUnit.SECONDS);
client.setReadTimeout(30, TimeUnit.SECONDS);
client.interceptors().add(httpLoggingInterceptor);
client.interceptors().add(httpInterceptor);
return client;
}
加入了http的log打印,同时重写了拦截器,目的是为了拦截返回体,进行base64转码。
Request orginRequest = chain.request();
Request requst = orginRequest.newBuilder()
.build();
Response response = chain.proceed(requst);
//解码返回体
Response pp = getBase64Response(response);
if (pp != null) return pp;
return response;
private Response getBase64Response(Response response) throws IOException {
if (response.body() != null) {
String bodyString = response.body().string();
/*解码*/
String pp = new String(
Base64.decode(bodyString, Base64.DEFAULT));
return response.newBuilder()
.body(ResponseBody.create(response.body().contentType(), pp))
.build();
}
return null;
}
ok,基本的网络访问到此结束,很简单没有什么难点,下面一篇文章将介绍如何下载一张图片。