HttpPost 适用于 Java 项目,但不适用于 Android 项目

2024-04-18

我为我的 Android 设备编写了一些代码,用于通过 HTTPS 登录网站并从结果页面中解析一些数据。一个HttpGet首先获取登录所需的一些信息,然后HttpPost执行实际的登录过程。

下面的代码在 Eclipse 中的 Java 项目中运行良好,该项目在构建路径上具有以下 JAR 文件:httpcore-4.1-beta2.jar, httpclient-4.1-alpha2.jar, httpmime-4.1-alpha2.jar, and 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 应用程序具有互联网权限,并且 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 吗?
  • 还有其他想法吗?

I've read https://stackoverflow.com/questions/2253061/secure-http-post-in-android a https://stackoverflow.com/questions/3663701/cant-do-a-http-post-to-a-web-service-from-my-android-app lot https://stackoverflow.com/questions/2935946/sending-images-using-http-post of https://stackoverflow.com/questions/3522140 posts https://stackoverflow.com/questions/874227 and code http://code.google.com/p/and-bookworm/source/browse/trunk/src/com/totsp/bookworm/data/HttpHelper.java,但我一无所获。


我现在已经放弃了HttpClient在 Android 上运行时提供来自服务器的预期响应的路由。相反,我重写了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方式无法正常工作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HttpPost 适用于 Java 项目,但不适用于 Android 项目 的相关文章

  • Apache HttpClient 摘要式身份验证

    基本上我需要做的是执行摘要身份验证 我尝试的第一件事是可用的官方示例here http svn apache org repos asf httpcomponents httpclient tags 4 0 1 httpclient src
  • Java 工具创建的 WSDL 文件的 WCF 序列化问题

    我的团队的任务是让几个内部开发的 NET 客户端应用程序连接到一些新的 Java Web 服务 Java Web 服务是第三方 供应商提供的 WSDL 文件 我们的团队修改 控制的能力有限 这意味着我们可能有权要求我们的供应商对 WSDL
  • 运行时签名是什么?

    当涉及到有界类型时 我对 Java 的类型擦除有一些理解上的问题 考虑一下 class Event From the API class FooEvent extends Event abstract class Foo
  • Java方法关键字“final”及其使用

    当我创建复杂类型层次结构 多个级别 每个级别几种类型 时 我喜欢使用final实现某些接口声明的方法上的关键字 一个例子 interface Garble int zork interface Gnarf extends Garble Th
  • Java - 多线程代码在更多内核上运行速度并不更快

    我只是在 4 核机器上运行一些多线程代码 希望它比在单核机器上更快 想法是这样的 我有固定数量的线程 在我的例子中每个核心一个线程 每个线程执行一个Runnable形式 private static int data data shared
  • 如何将 Netbeans 项目导入 Eclipse

    我想将我的 NetBeans 项目转移到 Eclipse 这是一个网络应用程序项目 我将 war 文件导入到 Eclipse 中 但无法获取 Java 文件 并且 war 文件给了我很多错误 导入整个项目的最佳方式是什么 另一种简单的方法如
  • java中如何将字符串日期转换为时间戳?

    我想在java中将字符串日期转换为时间戳 我编写了以下编码 我声明 date1 的日期是 7 11 11 12 13 14 SimpleDateFormat datetimeFormatter1 new SimpleDateFormat y
  • 如何更改操作栏上标题文本的大小?

    有一个ActionBar在每个 Android 4 0 应用程序上 它都有一个标题 我需要缩小这个尺寸 但我不明白我该怎么做 因为ActionBar不为其提供公共方法 Remark 我不想使用自定义视图 实际上 您可以对ActionBar
  • 如何使用 DynamicJasper 在 JasperReports 的页脚处显示每列的总和而不进行分组?

    我尝试使用下面的方法 drb addGlobalFooterVariable totalAmount DJCalculation SUM drb addGlobalFooterVariable basicAmount DJCalculati
  • 如何从指纹扫描仪获取输入并保存[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我正在使用 Android Marshmallow 和 Moto G4 以及一台设备进行测试 我想创建一个应用程序 它将接受指纹输入并
  • 读取pkcs12证书信息

    我在读取证书信息时遇到问题 我想以编程方式在 Android 中使用 java 和 bouncycastle 库来阅读完整信息 现在 我只是在控制台中使用 keytool 命令 gt keytool list keystore 1 p12
  • 如何在Android应用程序中添加g729编解码器?

    我正在开发一个用于拨打和接听电话的 SIP 应用程序 我想在我的应用程序中添加 G729 编解码器 目前我正在对开源项目进行分析SipDroid http code google com p sipdroid 如果我想让该应用程序支持 G7
  • ZonedDateTime 的 Jackson 反序列化问题

    我在反序列化我正在使用的服务期间使用的类中有以下字段 private ZonedDateTime transactionDateTime 我正在使用的服务可能会使用以下模式返回日期或日期时间 yyyy MM dd T HH mm ss SS
  • 破译Streamreduce函数

    为什么两者都是c1 and c2不被视为两个字符串 而是一个String和一个Integer Arrays asList duck chicken flamingo pelican stream reduce 0 c1 c2 gt c1 l
  • SAX:如何获取元素的内容

    我在理解使用 SAX 解析 XML 结构时遇到了一些困难 假设有以下 XML
  • Google 地图视图无法在模拟器上显示

    您好 我正在尝试在 Android 模拟器中显示地图 但它无法在地图视图中显示谷歌地图 并且也不从 Android 模拟器上的浏览器连接 www google com 那么是否有关于在模拟器上运行互联网的任何设置 谁能帮我解决这个问题 尝试
  • Java多线程和安全发布[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 看完之后 Java并发实践 http jcip net and OSGI 实践 http neilbartlett name blog osgi
  • 我应该如何处理 Android 应用程序中 http post 的服务器超时和错误代码响应?

    我的 Android 应用程序会向 URL 发送 http 帖子 例如http example com 电子邮件受保护 http example com abc php email abc xyz com因此 Android 应用程序基本上
  • Android:创建自定义形状进度条的最佳方法

    我想创建一个自定义形状的进度条 它会根据其进度改变颜色 但这几乎是一个不同的问题 那么 创建如下图所示的自定义形状进度条的最佳方法是什么 抱歉 MS Paint 绘图技巧不佳 为了拥有所有可能性 您应该创建一个从进度条派生的自定义类并完全重
  • Spring JPA - 通过 EmbeddedId 部分查找

    以下代码仅用于演示目的 My Entity豆看起来像这样 Entity class Employee EmbeddedId private EmployeeKey employeeKey private String firstName p

随机推荐

  • 从 URL 获取片段(哈希“#”后的值)[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 如何使用 PHP 选择 URL 中 符号后面的片段 我想要的结果是 photo45 这是一个示例 URL http example c
  • 当应用于带有facet_wrap的箱线图时删除一个tableGrob

    我使用下面的代码通过在 x 轴上创建的分类变量的汇总表来丰富箱线图 Libs require ggplot2 require gridExtra require grid require ggthemes Data data mtcars
  • “计算能力”是什么意思? CUDA?

    我是CUDA编程新手 对此了解不多 您能告诉我 CUDA 计算能力 是什么意思吗 当我在大学服务器上使用以下代码时 它向我显示了以下结果 for device 0 device lt deviceCount device cudaDevic
  • 如何禁用或隐藏我网站上不需要的 Disqus 广告?

    想象一下 有一天 突然 随机广告开始出现在您的网站上 最近 Disqus 开始在 Disqus 评论中强制添加不需要的广告 https wptavern com disqus hits sites with unwanted adverti
  • 更改 Swift Package 中的默认标头注释许可证

    我想更改 Swift 包中的默认标头 这可能吗 Note 我不想为了项目而改变它 这个有可能 如果你想改变 它适合您的项目 更改 Xcode 中的默认标头注释许可证 https stackoverflow com questions 238
  • 无法从三星设备上的通话记录中删除短信日志

    我尝试通过我的应用程序从设备中删除所有短信 但由于某种原因 短信日志仍然出现在某些三星设备的通话记录中 我尝试了一种更 激进 的方法 并使用以下 URI 删除ContentResolver content call log calls co
  • SonarQube 分支机构覆盖范围

    是否可以获取 SonarQube 中非主分支的代码覆盖率详细信息 我看到的其他分支的唯一两个选项卡是Issues and Code 我为每个分支运行相同的 Gradle JaCoCo Sonar 命令 gradlew report sona
  • 按元素数量拆分子列表中的列表

    在 python 中 如果我有元素列表 l a b c d e f 和一个数字列表 n 2 1 3 我如何拆分列表l通过中的数字n 并获取这个列表列表 a b c d e f 你可以使用islice gt gt gt from iterto
  • 语法错误:非默认参数遵循默认参数

    from os import system def a len1 hgt len1 til col 0 system mode con cols len1 lines hgt system title til system color co
  • 何时用引号将 shell 变量括起来?

    我应该或不应该在 shell 脚本中用引号括住变量吗 例如 下列说法正确的是 xdg open URL eq 2 or xdg open URL eq 2 如果是这样 为什么 一般规则 如果它可以为空或包含空格 或实际上任何空格 或特殊字符
  • 如何在调用子方法时强制调用父方法?

    我想要的是强制当子类从父类继承并且它重写父类方法而不显式调用它时 会引发错误 在错误类的初始化或调用该方法时可能会引发错误 目标是确保 Mother 类的用户执行 mother 方法中存在的一些操作 Example class Mother
  • React 无状态组件 this.refs..value?

    我不知道我这样做是否正确 如果我想从输入中获取值 我使用 this refs whatever value trim 但如果该输入是无状态函数组件 我如何检索 onSubmit 的值 经过研究 我知道现在这是不正确的 但是您应该如何从这些输
  • 未找到源,但无法搜索部分或全部事件日志。无法访问的日志:安全性[重复]

    这个问题在这里已经有答案了 我收到错误 未找到源 但无法获取部分或全部事件日志 搜索过 无法访问的日志 安全 当我运行下面的代码来捕获 Win 2K12 R2 服务器 IIS 8 5 上的错误时 EventLog elog new Even
  • 在 iOS 中添加/连接两个文本字段到一个标签中

    我有两个文本字段 在一个视图控制器中显示名称和首字母缩写 我想在另一个视图控制器中将两者显示为一个标签 我怎样才能做到这一点 要将数据从一个页面发送到另一页面 请查看所以在这里回答 https stackoverflow com quest
  • 使用 Sql Server 表中的值的 C# 枚举

    目前我有一个 SQL Server 2005 表 看起来有点像 ID name desc 1 ONE Value One 3 THREE Value Three 5 FIVE Value Five 该表对应于 C 中的枚举 如下所示 enu
  • win32com(python)错误

    我正在尝试在记事本中为我正在处理的程序自动执行操作 但我无法弄清楚我收到的错误消息 import os import win32com object win32com client Dispatch Notepad Application
  • 如何在 Javascript 中创建动态文件+下载链接? [复制]

    这个问题在这里已经有答案了 通常 HTML 页面可以包含可从服务器下载的文档 PDF 等 的链接 假设有一个启用 Javascript 的网页 是否可以从用户浏览器中动态创建一个文本文档 例如 并添加一个链接来下载该文档 而无需往返服务器
  • MAMP MySQL 无法连接:设置无效。

    我在 MAMP 灌输中遇到了问题 我没有改变它刚刚发生的任何事情 我完美地启动了 MAMP 它为 MySQL 服务器启动提供了绿灯 我可以使用 mysql 命令从终端连接到它 但是 当我尝试打开 phpMyAdmin 时 出现此错误 错误
  • 如何消除“最后一个语句应该返回一个值”警告?

    Sun Studio 12 1 打印警告 Warning The last statement should return a value 经常用于这样的功能 int f some code that may return if we en
  • HttpPost 适用于 Java 项目,但不适用于 Android 项目

    我为我的 Android 设备编写了一些代码 用于通过 HTTPS 登录网站并从结果页面中解析一些数据 一个HttpGet首先获取登录所需的一些信息 然后HttpPost执行实际的登录过程 下面的代码在 Eclipse 中的 Java 项目