版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/starexplode/article/details/81058988
使用HttpClient和OkHttp实现模拟登录方正教务系统
因为后面的项目需要,所以研究了一下方正教务系统的模拟登录。
首先分析一下,如何模拟登录需要什么参数。
下面的这个是验证码的url:
下面的这个是模拟登录需要的参数:
HttpClient模拟登录
HttpClient是Apahe下的一个项目,目的是为了方便Java发送请求,因为JDK提供的工具实在是他简陋了。
我这里是使用的maven构建的项目,所以在项目中添加下面的这个依赖即可:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
</dependency>
使用HttpClient的时候,第一步是创建一个HttpClient,它就相当于一个浏览器一样,所有的请求都是通过它发送出去的。
发送Get请求的时候,创建一个HttpGet即可,然后使用HttpClient发送出去。Post请求类似。
public class HttpClientDemoTest5 {
public static final String BASEURL = "http://xxx.xxx.xxx/";
public static final String LOGIN = "default2.aspx";
public static final String HIDDEN_NAME = "__VIEWSTATE";
public static final String HIDDEN_VALUE = "dDwxNTMxMDk5Mzc0Ozs+lYSKnsl/mKGQ7CKkWFJpv0btUa8=";
public static final String LOGIN_USERNAME = "txtUserName";
public static final String LOGIN_PASSWORD = "TextBox2";
public static final String LOGIN_VALIDE_CODE = "txtSecretCode";
public static final String URL_VALIDE_CODE = "CheckCode.aspx";
public static void main(String[] args) throws IOException {
// 创建一个HttpClient
HttpClient httpClient = HttpClients.createDefault();
// 首先发送一个请求,和该网站建立连接
HttpGet httpGet = new HttpGet(BASEURL);
// 发送请求,得到响应HttpResponse
HttpResponse first = httpClient.execute(httpGet);
// 获取headers中的Cookie,因为Cookie中有sessionID
Header[] headers = first.getHeaders("Set-Cookie");
String sessionId = headers[0].getValue();
// 重新建立一个header
Header session = new BasicHeader("Cookie", sessionId);
// 获取验证码的请求
HttpGet validateCode = new HttpGet(BASEURL + "/" + URL_VALIDE_CODE);
// 它的响应是一张图片,将图片写入文件保存
HttpResponse response = httpClient.execute(validateCode);
HttpEntity entity = response.getEntity();
if (entity != null) {
File file = new File("validate.png");
if (file.exists())
file.delete();
InputStream inputStream = entity.getContent();
Files.copy(inputStream, file.toPath());
}
// 发送POST请求,模拟登录
HttpPost httpPost = new HttpPost("http://222.24.62.120/" + LOGIN);
List<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair(HIDDEN_NAME, HIDDEN_VALUE));
params.add(new BasicNameValuePair(LOGIN_USERNAME, "xxxxxxx"));
params.add(new BasicNameValuePair("TextBox1", "xxxxxxx"));
params.add(new BasicNameValuePair(LOGIN_PASSWORD, "xxxxxxxxx"));
params.add(new BasicNameValuePair("RadioButtonList1", "学生"));
params.add(new BasicNameValuePair("Button1", ""));
Scanner scanner = new Scanner(System.in);
// 输入验证码
String code = scanner.nextLine();
params.add(new BasicNameValuePair(LOGIN_VALIDE_CODE, code));
httpPost.setEntity(new UrlEncodedFormEntity(params));
// 如果状态是302,那么表示登录成功。这里是有一个跳转,但是HttpClient并不会跳转
if (response.getStatusLine().getStatusCode() == 302) {
System.out.println("登录成功");
}
// 获取跳转的url
Header headerLocation = response.getFirstHeader("Location");
String location = headerLocation.getValue();
System.out.println(location);
HttpGet mypage = new HttpGet(BASEURL + location);
// 这个需要添加上面保存的session,是因为下面的httpClient发送请求的时候会一直发送,无法产生结果
// 这个具体不知道是为什么,所以在这里重新创建了一个httpClient,如下
mypage.setHeader(session);
// HttpResponse mypageResponse = httpClient.execute(mypage);
HttpResponse mypageResponse = HttpClients.createDefault().execute(mypage);
HttpEntity mypageEntiry = mypageResponse.getEntity();
if (mypageEntiry != null) {
InputStream content = mypageEntiry.getContent();
byte[] bytes = new byte[1024];
while (content.read(bytes) != -1)
System.out.println(new String(bytes, "GBK"));
}
}
}
OkHttp模拟登录
在项目中添加OkHttp的依赖:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.11.0</version>
</dependency>
上面的HttpClient模拟登录时,不知道为什么,最后的httpClient的请求总是得不到结果,一直等待,所以就有研究了下如何使用OkHttp模拟登录,不得不说的是OkHttp的模拟登录要比HttpClient简单。
流程和上面差不多,首先创建一个OkHttpClient。
这里重写了CookJar是的OkHttpClient能够自动管理Cookie。
// 设置OKHttpClient自动管理Cookie
private static OkHttpClient mOkHttpClient = new OkHttpClient.Builder().cookieJar(new CookieJar() {
private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
cookieStore.put(url.host(), cookies);
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
List<Cookie> cookies = cookieStore.get(url.host());
return cookies != null ? cookies : new ArrayList<Cookie>();
}
}).build();
下面的基本上和httpClient相似。
public class OkHttpDemoTest {
// 设置OKHttpClient自动管理Cookie
private static OkHttpClient mOkHttpClient = new OkHttpClient.Builder().cookieJar(new CookieJar() {
private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
cookieStore.put(url.host(), cookies);
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
List<Cookie> cookies = cookieStore.get(url.host());
return cookies != null ? cookies : new ArrayList<Cookie>();
}
}).build();
public static final String BASEURL = "http://xxx.xxx.xxx.xxx/";
public static final String LOGIN = "default2.aspx";
public static final String HIDDEN_NAME = "__VIEWSTATE";
public static final String HIDDEN_VALUE = "dDwxNTMxMDk5Mzc0Ozs+lYSKnsl/mKGQ7CKkWFJpv0btUa8=";
public static final String LOGIN_USERNAME = "txtUserName";
public static final String LOGIN_PASSWORD = "TextBox2";
public static final String LOGIN_VALIDE_CODE = "txtSecretCode";
public static final String URL_VALIDE_CODE = "CheckCode.aspx";
public static void main(String[] args) throws IOException {
Request request = new Request.Builder().url(BASEURL).build();
Call call = mOkHttpClient.newCall(request);
try {
Response response = call.execute();
} catch (IOException e) {
e.printStackTrace();
}
Request validateRequest = new Request.Builder()
.url(BASEURL + URL_VALIDE_CODE).build();
Call validateCall = mOkHttpClient.newCall(validateRequest);
try {
Response validateResponse = validateCall.execute();
File file = new File("validateCode.png");
if (file.exists())
file.delete();
InputStream inputStream = validateResponse.body().byteStream();
Files.copy(inputStream, file.toPath());
} catch (IOException e) {
e.printStackTrace();
}
FormBody.Builder formBodyBuilder = new FormBody.Builder();
formBodyBuilder.add(HIDDEN_NAME, HIDDEN_VALUE);
formBodyBuilder.add(LOGIN_USERNAME, "xxxxxx");
formBodyBuilder.add("TextBox1", "xxxxxxx");
formBodyBuilder.add(LOGIN_PASSWORD, "xxxxxxxxx");
formBodyBuilder.add("RadioButtonList1", "学生");
formBodyBuilder.add("Button1", "");
Scanner scanner = new Scanner(System.in);
String code = scanner.nextLine();
formBodyBuilder.add(LOGIN_VALIDE_CODE, code);
RequestBody requestBody = formBodyBuilder.build();
Request loginRequest = new Request.Builder().url(BASEURL + LOGIN)
.post(requestBody)
.build();
// 不同于httpClient的是Okhttp会自动跳转
Response response = mOkHttpClient.newCall(loginRequest).execute();
try {
byte[] bytes = new byte[1024];
InputStream is = response.body().byteStream();
while (is.read(bytes) != -1)
System.out.println(new String(bytes, "GBK"));
} catch (IOException e) {
e.printStackTrace();
}
}
}