HttpPost在Java项目中工作,而不是在Android中工作

我已经为我的Android设备编写了一些代码,通过https登录到一个网站,并从结果页面中解析出一些数据。 HttpGet首先会获得登录所需的一些信息,然后是HttpPost来执行实际的登录过程。

下面的代码在Eclipse中的Java项目中很好用,它在构建路径中具有以下Jar文件: httpcore-4.1-beta2.jarhttpclient-4.1-alpha2.jarhttpmime-4.1-alpha2.jarcommons-logging-1.1.1.jar httpmime-4.1-alpha2.jar commons-logging-1.1.1.jar

public static MyBean gatherData(String username, String password) {
    MyBean myBean = new MyBean();
    try {
        HttpResponse response = doHttpGet(URL_PAGE_LOGIN, null, null);
        System.out.println("Got login page");
        String content = EntityUtils.toString(response.getEntity());
        String token = ContentParser.getToken(content);
        String cookie = getCookie(response);
        System.out.println("Performing login");
        System.out.println("token = "+token +" || cookie = "+cookie);
        response = doLoginPost(username,password,cookie, token);
        int respCode = response.getStatusLine().getStatusCode();
        if (respCode != 302) {
            System.out.println("ERROR: not a 302 redirect!: code is ""+ respCode+""");
            if (respCode == 200) {
                System.out.println(getHeaders(response));
                System.out.println(EntityUtils.toString(response.getEntity()).substring(0, 500));
            }
        } else {
            System.out.println("Logged in OK, loading account home");
            // redirect handler and rest of parse removed
        }
    }catch (Exception e) {
        System.out.println("ERROR in gatherdata: "+e.toString());
        e.printStackTrace();
    }
    return myBean;
}
private static HttpResponse doHttpGet(String url, String cookie, String referrer) {
    try {
        HttpClient client = new DefaultHttpClient();
        client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
        client.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, "UTF-8");
        HttpGet httpGet = new HttpGet(url);
        httpGet.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
        httpGet.setHeader(HEADER_USER_AGENT,HEADER_USER_AGENT_VALUE);
        if (referrer != null && !referrer.equals("")) httpGet.setHeader(HEADER_REFERER,referrer);
        if (cookie != null && !cookie.equals("")) httpGet.setHeader(HEADER_COOKIE,cookie);
        return client.execute(httpGet);
    } catch (Exception e) {
        e.printStackTrace();
        throw new ConnectException("Failed to read content from response");
    }
}
private static HttpResponse doLoginPost(String username, String password, String cookie, String token) throws ClientProtocolException, IOException {
    try {
        HttpClient client = new DefaultHttpClient();
        client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
        client.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, "UTF-8");
        HttpPost post = new HttpPost(URL_LOGIN_SUBMIT);
        post.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
        post.setHeader(HEADER_USER_AGENT,HEADER_USER_AGENT_VALUE);
        post.setHeader(HEADER_REFERER, URL_PAGE_LOGIN);
        post.setHeader(HEADER_COOKIE, cookie);
        post.setHeader("Content-Type","application/x-www-form-urlencoded");
        List<NameValuePair> formParams = new ArrayList<NameValuePair>();
        formParams.add(new BasicNameValuePair("org.apache.struts.taglib.html.TOKEN", token));
        formParams.add(new BasicNameValuePair("showLogin", "true"));
        formParams.add(new BasicNameValuePair("upgrade", ""));
        formParams.add(new BasicNameValuePair("username", username));
        formParams.add(new BasicNameValuePair("password", password));
        formParams.add(new BasicNameValuePair("submit", "Secure+Log+in"));
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams,HTTP.UTF_8);
        post.setEntity(entity);
        return client.execute(post);
    } catch (Exception e) {
        e.printStackTrace();
        throw new ConnectException("ERROR in doLoginPost(): "+e.getMessage());
    }
}

服务器(不受我控制)在登录成功时返回302重定向,如果失败并返回200,则重新加载登录页面。 当使用上面的Jar文件运行时,我得到了302重定向,但是如果我在构建路径上使用1.6 Android Jar文件从Android项目运行完全相同的代码,则会从服务器获得200响应。 在2.2设备上运行代码时,我得到相同的200响应。

我的Android应用程序具有Internet权限,并且HttpGet可以正常工作。 我假设问题出在HttpPost(或其他一些类)在Android Jar版本和较新的Apache版本之间的某种重要方式上有所不同。

我已经尝试将Apache库添加到Android项目的构建路径,但由于重复类,我得到如下消息: INFO/dalvikvm(390): DexOpt: not resolving ambiguous class 'Lorg/apache/http/impl/client/DefaultHttpClient;' 在日志中。 我也尝试使用MultipartEntity而不是UrlEncodedFormEntity但我得到相同的200结果。

所以,我有几个问题:
- 我可以强制运行在android下的代码使用较新的Apache库优先于Android版本吗?
- 如果没有,有没有人有任何想法如何改变我的代码,以便它与Android Jar协同工作?
- 有没有其他的,完全不同的方法来做Android的HttpPost?
- 任何其他想法?

我读了很多帖子和代码,但我没有得到任何地方。 我一直坚持这一两天,我不知道如何让事情发挥作用,所以我会在这一点上尝试任何事情。 提前致谢。


在Android上运行时,我已经放弃让HttpClient路由给服务器预期的响应。 相反,我改写了上面的doPost方法来代替使用HttpsURLConnection 。 这是新的(工作)版本,希望对某人有用。

private static LoginBean altPost(String username, String password, String cookie, String token){
    LoginBean loginBean = new LoginBean();
    HttpsURLConnection urlc = null;
    OutputStreamWriter out = null;
    DataOutputStream dataout = null;
    BufferedReader in = null;
    try {
        URL url = new URL(URL_LOGIN_SUBMIT);
        urlc = (HttpsURLConnection) url.openConnection();
        urlc.setRequestMethod("POST");
        urlc.setDoOutput(true);
        urlc.setDoInput(true);
        urlc.setUseCaches(false);
        urlc.setAllowUserInteraction(false);
        urlc.setRequestProperty(HEADER_USER_AGENT, HEADER_USER_AGENT_VALUE_FF);
        urlc.setRequestProperty("Cookie", cookie);
        urlc.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
        String output = "org.apache.struts.taglib.html.TOKEN="+ URLEncoder.encode(token, HTTP.UTF_8)
                +"&showLogin=true&upgrade=&username="+ URLEncoder.encode(username, HTTP.UTF_8)
                +"&password="+ URLEncoder.encode(password, HTTP.UTF_8)+"&submit="
                +URLEncoder.encode("Secure+Log+in", HTTP.UTF_8);
        dataout = new DataOutputStream(urlc.getOutputStream());
        // perform POST operation
        dataout.writeBytes(output);
        // get response info
        loginBean.setResponseCode(urlc.getResponseCode());
        // get required headers
        String headerName = null;
        StringBuffer newCookie = new StringBuffer(100);
        String redirectLocation = "";
        for (int i=1; (headerName = urlc.getHeaderField(i)) != null;i++) {
            if (headerName.indexOf(COOKIE_VALUE_SESSION) > -1) {
                if (newCookie.length() > 0) {newCookie.append("; ");}
                newCookie.append(headerName);
            }
            if (headerName.indexOf(COOKIE_VALUE_AUTH) > -1) {
                if (newCookie.length() > 0) {newCookie.append("; ");}
                newCookie.append(headerName);
            }
            if (headerName.indexOf("https://") > -1) {
                redirectLocation = headerName;
            }
        }
        loginBean.setCookie(newCookie.toString());
        loginBean.setRedirectUrl(redirectLocation);

        in = new BufferedReader(new InputStreamReader(urlc.getInputStream()),8096);
        String response;
        // write html to System.out for debug
        while ((response = in.readLine()) != null) {
            System.out.println(response);
        }
        in.close();
    } catch (ProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (out != null) {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (in != null) {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return loginBean;
}

我仍然不知道为什么HttpClient方式无法正常工作。


为了避免碰撞使用这个jar作为httpclient

httplib的

这篇文章也会非常有用

堆栈溢出帖子


这个网站可能会进行用户代理检测,并且实际上会返回不同的结果,因为它是Android? 鉴于200意味着成功,为什么它必须给302而不是200? 你是否打印出返回200时得到的结果,并提供其他信息?

链接地址: http://www.djcxy.com/p/22045.html

上一篇: HttpPost works in Java project, not in Android

下一篇: How to "scan" a website (or page) for info, and bring it into my program?