前言
之前写过一篇博客是用python的urllib库来模拟登录jaccount。后来想要做一个APP,其中一个模块需要登录jaccount,于是想要用java来实现同样的功能。这次采用的是httpclient 4.5,可以自行从官网下载并添加到自己的工程中。
注意
- httpclient 4.5可以自动管理cookie。也就是说在工程中如果使用同一个httpclient多次访问网页,那么它会自动携带服务器返回的cookie信息。
- 这是我走过最大的一个弯路,httpclient 的GET请求方式可以自动进行重定向(当服务器返回302时自动进行处理),但是httpclient的POST方式则不会。python的urllib库的GET和POST方式都自动重定向,在这个地方卡了很长时间。解决方法有两种,一是手动处理,二是采用工具,
HttpClientBuilder builder = HttpClients.custom()
.disableAutomaticRetries() //关闭自动处理重定向
.setRedirectStrategy(new LaxRedirectStrategy());//利用LaxRedirectStrategy处理POST重定向问题 - httpclient的请求地址都要加上“http://”否则会返回错误信息。
源代码
public class Jaccount {
private static String captchaUrl = "https://jaccount.sjtu.edu.cn/jaccount/captcha";
private static String loginUrl = "http://electsys.sjtu.edu.cn/edu/login.aspx";
private static String postUrl = "https://jaccount.sjtu.edu.cn/jaccount/ulogin";
private static String openUrl = "http://electsys.sjtu.edu.cn/edu/student/examArrange/examArrange.aspx";
private static RequestConfig config = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build();
private static CookieStore cookieStore = new BasicCookieStore();
private static HttpClientContext context = HttpClientContext.create();
private static CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(config)
.setDefaultCookieStore(cookieStore).build();
public static void login() {
String sid = "";
String returl = "";
String se = "";
String v = "";
String captcha = "";
context.setCookieStore(cookieStore);
String responseBody = getHtml(loginUrl);
captcha = getCaptcha();
Pattern r = Pattern.compile("name=\"sid\" value=\"(.+?)\">");
Matcher matcher = r.matcher(responseBody);
while (matcher.find())
sid = matcher.group(1);
r = Pattern.compile("name=\"returl\" value=\"(.+?)\">");
matcher = r.matcher(responseBody);
while (matcher.find())
returl = matcher.group(1);
r = Pattern.compile("name=\"se\" value=\"(.+?)\">");
matcher = r.matcher(responseBody);
while (matcher.find())
se = matcher.group(1);
r = Pattern.compile("name=\"v\" value=\"(.+?)\">");
matcher = r.matcher(responseBody);
while (matcher.find())
v = matcher.group(1);
// System.out.println("se " + se);
// System.out.println("returl " + returl);
// System.out.println("sid " + sid);
// System.out.println("v " + v);
List<NameValuePair> list = new ArrayList<NameValuePair>();
list.add(new BasicNameValuePair("sid", sid));
list.add(new BasicNameValuePair("returl", returl));
list.add(new BasicNameValuePair("se", se));
list.add(new BasicNameValuePair("v", v));
list.add(new BasicNameValuePair("user", "......"));
list.add(new BasicNameValuePair("pass", "......"));
list.add(new BasicNameValuePair("captcha", captcha));
HttpPost httpPost = new HttpPost(postUrl);
try {
httpPost.setEntity(new UrlEncodedFormEntity(list, Consts.UTF_8));
CloseableHttpResponse response = httpClient.execute(httpPost, context);
// System.out.println("POST Response Status:: " +
response.getStatusLine().getStatusCode());
//这里会返回302,所以用GET方式,进行重定向操作
String locationUrl = response.getLastHeader("Location").getValue();
// System.out.println("POST Response Location:: " + locationUrl);
getHtml("http://jaccount.sjtu.edu.cn" + locationUrl);
// System.out.println("POST Response Status:: " +
// response.getStatusLine().getStatusCode());
// locationUrl = response.getLastHeader("Location").getValue();
// System.out.println("POST Response Location:: " + locationUrl);
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity, "utf-8");
System.out.println(result);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static String getCaptcha() {
String captcha = "";
File file = new File("captcha.jpg");
if (file.exists())
file.delete();
InputStream input = null;
FileOutputStream out = null;
try {
HttpGet httpGet = new HttpGet(captchaUrl);
CloseableHttpResponse response = httpClient.execute(httpGet, context);
HttpEntity entity = response.getEntity();
input = entity.getContent();
int i = -1;
byte[] by = new byte[1024];
out = new FileOutputStream(file);
while ((i = input.read(by)) != -1)
out.write(by);
input.close();
out.close();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (UnsupportedOperationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.print("input the captch: ");
Scanner scan = new Scanner(System.in);
captcha = scan.nextLine();
scan.close();
return captcha;
}
public static String getHtml(String url) {
HttpGet httpget = new HttpGet(url);
// Create a response handler
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String responseBody = "";
try {
responseBody = httpClient.execute(httpget, responseHandler, context);
} catch (Exception e) {
e.printStackTrace();
responseBody = null;
} finally {
httpget.abort();
}
return responseBody;
}
public static void main(String[] args) {
login();
//访问考试安排界面测试是否登录成功
System.out.println(getHtml(openUrl));
}
}