上次实现了登录后拿到教务网站首页的源数据显示在UI上,这次实现了不同Activity间跳转和成绩信息的查询。
UI还没有做,上简陋的效果图:
当用户登录之后,整个应用程序使用的是同一个HttpClient向目标页请求信息。这里稍微纠结了一下,一开始使用的是Bundle传值,使用Serializable接口,但是HttpClient不可用,修改源文件又太麻烦,再定义一个类也没有成功。折腾了一圈之后才想起来使用单例模式。。。汗。。。
下面是单例模式代码:
package com.example.asa.easyxiian;
import org.apache.commons.httpclient.HttpClient;
import java.io.Serializable;
/**
* Created by asa on 2018/4/24.
*/
public class Client{
private static HttpClient mHttpClient = null;
private Client(){
}
public static HttpClient getHttpClient(){
if(mHttpClient == null){
mHttpClient = new HttpClient();
}
return mHttpClient;
}
}
接下来就容易多了,在不同Activity内使用上一次实现的请求即可。
成绩列表布局文件(草稿):
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.asa.easyxiian.ScoresActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/scores_info"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</ScrollView>
</android.support.constraint.ConstraintLayout>
ScoresActivity:
package com.example.asa.easyxiian;
import android.content.Intent;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.jsoup.Jsoup;
import org.jsoup.select.Elements;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.io.IOException;
import java.util.ArrayList;
public class ScoresActivity extends AppCompatActivity {
final static String scoresInfoURL = "http://jwxt.xidian.edu.cn/gradeLnAllAction.do?type=ln&oper=fainfo&fajhh=372";
HttpClient mClient = Client.getHttpClient();
TextView mTextView;
String mClassInfo;
String mJSESSION;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scores);
Intent intent = this.getIntent();
mJSESSION = intent.getStringExtra("JSESSION");
mTextView = (TextView)findViewById(R.id.scores_info);
mTextView.setText("");
new getScoresInformationTask().execute(scoresInfoURL);
}
private class getScoresInformationTask extends AsyncTask<String, Void, ArrayList<ScoreForOneProject>> {
@Override
protected ArrayList<ScoreForOneProject> doInBackground(String... strings) {
String result = null;
GetMethod getMethod = null;
String bodyMessage = null;
ArrayList<ScoreForOneProject> sheet = new ArrayList<>();
org.jsoup.nodes.Document document;
try {
getMethod = NetworkUtils.getMethodUseCookie(mClient, mJSESSION, strings[0]);
bodyMessage = getMethod.getResponseBodyAsString();
result = bodyMessage;
document = Jsoup.parseBodyFragment(bodyMessage);
org.jsoup.select.Elements element = document.select("[class=\"titleTop2\"]").select("[class=\"odd\"]");
for (int i = 0;i < element.size();i++){
Elements project = element.get(i).select("td");
String name = project.get(2).text();
String score = project.get(6).text();
sheet.add(new ScoreForOneProject(name,score));
}
mClassInfo = result;
} catch (IOException e) {
Log.e("ScoresActivity", "使用Cookie的GET失败。");
}
return sheet;
}
@Override
protected void onPostExecute(ArrayList<ScoreForOneProject> sheet) {
for (int i = 0;i < sheet.size();i++)
mTextView.append(sheet.get(i).getmName() + " " + sheet.get(i).getmScore() + "\n\n");
}
}
}
这里使用Jsoup获取表格中的有效数据。
MainActivity:
package com.example.asa.easyxiian;
import android.content.Intent;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import java.io.IOException;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
public class MainActivity extends AppCompatActivity {
final static String loginUrl1 = "http://ids.xidian.edu.cn/authserver/login?service=http%3A%2F%2Fjwxt.xidian.edu.cn%2Fcaslogin.jsp";
final static String classInforURL = "http://jwxt.xidian.edu.cn/xkAction.do?actionType=6";
private EditText mEditTextUserName;
private EditText mEditTextPassWord;
private String mUserName;
private String mPassWord;
HttpClient mClient;
TextView mTextViewUserName;
TextView mTextViewPassWord;
private GetMethod mGetMethod;
String mJSESSION;
boolean mIsLogIn = false;
String mClassInfo;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextViewUserName = (TextView) findViewById(R.id.user_name_display);
mTextViewPassWord = (TextView) findViewById(R.id.password_display);
ImageView background = (ImageView) findViewById(R.id.first_page_background);
background.setAlpha(80);
}
public void LogIn(View view) {
mEditTextUserName = (EditText) findViewById(R.id.user_name);
mUserName = mEditTextUserName.getText().toString();
mEditTextPassWord = (EditText) findViewById(R.id.password);
mPassWord = mEditTextPassWord.getText().toString();
new LogInTask().execute();
//new getClassesInformationTask().execute(classInforURL);
while (!mIsLogIn){}
Bundle bundle = new Bundle();
bundle.putString("JSESSION",mJSESSION);
Intent intent = new Intent(MainActivity.this,MenuActivity.class);
intent.putExtras(bundle);
startActivity(intent);
}
private class LogInTask extends AsyncTask<String, Void, Boolean> {
@Override
protected Boolean doInBackground(String... strings) {
mClient = Client.getHttpClient();
String data[] = new String[2];
String result = null;
//GET请求拿到JSESSIONID
try {
GetMethod getMethod = NetworkUtils.getAction(mClient, loginUrl1);
data = NetworkUtils.getData(getMethod);
getMethod.releaseConnection();
} catch (IOException e) {
Log.e("MainActivity : ", "第一步GET请求失败");
}
//用拿到的JSESSIONID填充POST网址
String postUrl = "http://ids.xidian.edu.cn/authserver/login;jsessionid="
+ data[0] + "?service=http%3A%2F%2Fjwxt.xidian.edu.cn%2Fcaslogin.jsp";
String urlResponse = null;
String JSESSIONID2 = null;
//POST请求发送登录数据,拿到第二步网址urlResponse
try {
PostMethod postMethod = NetworkUtils.postAction(mClient, postUrl, mUserName, mPassWord, data[0], data[1]);
urlResponse = postMethod.getResponseHeader("Location").toString().split(" ")[1];
} catch (IOException e) {
Log.e("MainActivity : ", "第二步POST请求失败");
}
String logInPage = null;
//第二次GET请求进入登录界面,拿到第二个JSESSIONID
try {
GetMethod getMethod = new GetMethod(urlResponse);
getMethod.setFollowRedirects(false);
int statusCode = mClient.executeMethod(getMethod);
JSESSIONID2 = getMethod.getResponseHeader("Set-Cookie").getValue().split(";")[0].trim()
.split("=")[1];
Log.e("Set-Cookie", JSESSIONID2 + "");
//检查是否登录成功
Log.e("Status code", "" + statusCode);
logInPage = getMethod.getResponseHeader("Location").toString().split(" ")[1];
Log.e("Response page", "" + logInPage);
} catch (IOException e) {
Log.e("MainActivity : ", "第二步GET请求失败");
}
//进入登录后页面
GetMethod getMethod = new GetMethod(logInPage);
getMethod.setFollowRedirects(false);
getMethod.addRequestHeader(new Header("Cookie", "JSESSION=" + JSESSIONID2));
try {
mClient.executeMethod(getMethod);
result = getMethod.getResponseBodyAsString();
mGetMethod = getMethod;
mJSESSION = JSESSIONID2;
mIsLogIn = true;
} catch (IOException e) {
Log.e("MainActivity : ", "进入登录后页面失败");
}
return mIsLogIn;
}
}
}