使用HttpClient和OkHttp实现模拟登录方正教务系统

版权声明:本文为博主原创文章,未经博主允许不得转载。 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();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/starexplode/article/details/81058988