定义retrofit的接口
public interface ApiService {
@GET("{part}/")
Observable getNewsData(@Path("part") String part, @Query("key") String key, @Query("num") String num, @Query("page") int page);
@FormUrlEncoded
@POST("reader/redr_verify.php")
Call getMyBookData(@Header("Cookie") String cookie,@FieldMap Map params);
@FormUrlEncoded
@POST("Default.aspx")
Call allSeatSearch(@FieldMap Map params);
@GET("FunctionPages/Statistical/LibraryUsedStat.aspx")
Call getPhoto();
@GET("reader/book_lst.php")
Call getMyBookDataDetail(@Header("Cookie") String cookie);
@GET("reader/captcha.php")
Call getCookieData();
}
1.实现模拟登录图书馆,查看《我的借阅》
首先发现登录界面需要验证码,所以第一步获取验证码图片,拿到COOKIE保存起来。代码如下。
public void requestTestOkhttp(){
OkHttpClient okHttpClient=new OkHttpClient();
Request request=new Request.Builder().get()
.url("http://202.194.40.71:8080/reader/captcha.php")
.build();
okHttpClient.newCall(request).enqueue(new okhttp3.Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException {
Message message=handler.obtainMessage();
if(response.isSuccessful()){
message.what=1;
message.obj=response.body().bytes();
handler.sendMessage(message);
String s=response.headers().get("Set-Cookie").toString();
String[] cookieArray=s.split(";");
Log.d("SearchMyBook",cookieArray[0]);
editor=pref.edit();
editor.putString("cookie",cookieArray[0]);//PHPSESSID=xxxxxxx;
editor.apply();
}else{
Log.d("SearchMyBook","response is not successful");
}
}
});
}
因为okhttp的onresponse发生在子线程,无法进行UI操作,所以此处通过Handler进行图片的加载。通过response.body().bytes()转换成字节流传送,通过字节数组btye[]保存,通过BitmapFactory.decodeByteArray(result,0,result.length)将字节数组转换成bitmap图片,实现验证码获取下载。
(此处用retrofit转字节数组不成功,暂时搁置挖个坑以后过来填)
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case 1:
byte[] result=(byte[])msg.obj;
Bitmap bitmap=BitmapFactory.decodeByteArray(result,0,result.length);
img.setImageBitmap(bitmap);
break;
}
}
};
第二步携带COOKIE进行POST请求登录,此处通过RETROFIT完成。
通过Map携带参数。
public void requestMyBook(Map params){
Retrofit retrofit=new Retrofit.Builder()
.baseUrl("http://202.194.40.71:8080/")
.addConverterFactory(ScalarsConverterFactory.create())
.build();
ApiService service=retrofit.create(ApiService.class);
Call call=service.getMyBookData(pref.getString("cookie",""),params);
call.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
//tv_mybook_search.setText(response.body().toString());
requestMyBookDetail();
}
@Override
public void onFailure(Call call, Throwable t) {
Toast.makeText(SearchMyBook.this,"请求失败",Toast.LENGTH_SHORT).show();
}
});
}
第三步,登录后进行get请求获取具体的个人借阅页面,根据自己的需要新建实体类,此处我只需要借书名称,借出时间和应还时间。然后根据获得的H5代码通过JSOUP进行解析。添加对应的数据。
public void requestMyBookDetail(){
Retrofit retrofit=new Retrofit.Builder()
.baseUrl("http://202.194.40.71:8080/")
.addConverterFactory(ScalarsConverterFactory.create())
.build();
ApiService service=retrofit.create(ApiService.class);
Call call=service.getMyBookDataDetail(pref.getString("cookie",""));
call.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
if(response.isSuccessful()) {
StringBuilder sb=new StringBuilder();
Document doc= Jsoup.parse(response.body().toString());
// Elements content=doc.getElementsByAttributeValue("class","blue");
// for(Element link :content)
// {
// sb.append(link.getElementsByTag("a").text().toString()+"\r\n");
//
// }
//whitetext标签查询
// Elements content=doc.getElementsByAttributeValue("class","whitetext");
// for(Element link :content)
// {
// sb.append(link.getElementsByAttributeValue("width","35%").text().toString());
// sb.append(link.getElementsByAttributeValue("width","13%").text().toString());
// }
// tv_mybook_search.setText(sb.toString());
Element table=doc.getElementsByTag("table").get(0);
Element tbody=table.getElementsByTag("tbody").get(0);
Elements trs=tbody.getElementsByTag("tr");
for(int i=1;i call, Throwable t) {
Toast.makeText(SearchMyBook.this,"请求失败",Toast.LENGTH_SHORT).show();
}
});
}
第四步在BUTTON点击事件中进行请求,输入参数
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Map params=new HashMap<>();
params.put("number","******");
params.put("passwd","******");
params.put("captcha", editText.getText().toString());
params.put("select","cert_no");
params.put("returnUrl","");
requestMyBook(params);
Log.d("SearchMyBook",params.toString());
}
});
这样一个模拟登录请求就完成了。下面介绍今天做的另一部分,它让我浪费了很久的时间,感觉自己是真的蠢!!!!!!!
2.这一部分做的是座位的查询,主要卡在了post登录和图片的获取上。
我开始直接用post但是无法登录,后来发现先post一次获得返回的cookie,然后带着cookie才可以登录!(又栽在了cookie上),然后一层一层地访问,直到访问到最后一层发现图片格式很奇怪,百度发现是AJAX生成的,然后我就苦恼了,以为无法通过jsoup获取,因为发现在网页里无法通过输入链接打开,但是最后最后在ANDroid端竟然下载成功了,当我发现打印的Headers信息里,content-type变成了jpg,心情难以抑制的激动啊。。还好舍友提了一次,我抱着不太可能心态尝试了一下竟然成功了!此处先记一下,还是不太理解为什么在Android端可以访问,如果是因为cookie缘故pc上不是自动保存cookie了吗。。回头再去咨询一下大神。。
不管怎么说总算下载成功了,没白花费这么久,开心又希望下次能更快一点。。代码部分还是太冗余,明天尝试进行一下优化封装!!fight!