【问题标题】:POST doesn't seem to work with my form from HttpURLConnectionPOST 似乎不适用于来自 HttpURLConnection 的表单
【发布时间】:2010-06-22 13:04:57
【问题描述】:

我正在尝试使用 java 登录报告系统。到目前为止,我已经尝试了许多使用 HttpURLConnection 的不同实现。我试图发布的 HTML 归结为:

<form name="logonForm" method="POST" action="http://remoteserver/logon.object">
<input type="hidden" name="qryStr" value=""> 
<input type="hidden" name="cmsVisible" value="true"> 
<input type="hidden" name="authenticationVisible" value="true"> 
<input type="hidden" name="referer" value="">
<input type="hidden" name="refererFormData" value="">
<input type="hidden" name="isFromLogonPage" value="true">
<input type="text" name="cms" value="xxxxx" class="textfield" id="apsTextEdit">
<input type="text" name="username" value="xxxxx"class="textfield" id="usernameTextEdit">
<input type="text" name="password" value="xxxxx"class="textfield" id="passwordTextEdit">
<select name="authType"id="authenticationSelectBox">
<option selected value='xxxxx'>xxxxx</select>
<input type="submit" name="SUBMIT">
</form>

我知道这个表单提供了有效的输入,因为当我在浏览器中单击提交时,它会将我登录到我的报告系统中。但是,当我发送编程请求时,我总是将上述 html 作为响应返回。注意我已经尝试了大约一百万个使用 HttpURLRequest 的实现。一个例子:

        OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream());
        wr.write(parameters);
        wr.flush();

        // Get the response
        BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        String line;
        String allLines = "";
        while ((line = rd.readLine()) != null) {
            allLines += "\n" + line; // Process line...
        }
        wr.close();
        rd.close();
        return allLines;

“参数”的范围从零到我发布的 HTML 中的每个 URL 编码参数,连接(目前,正如我尝试过的其他配置一样)设置如下:

        connection = (HttpURLConnection) url.openConnection();
        HttpURLConnection.setFollowRedirects(true);
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setRequestMethod("POST");
        connection.setAllowUserInteraction(false);
        connection.setRequestProperty("Content-type", "application/x-www-form-urlencoded; charset=" + "UTF-8");
        connection.setUseCaches(false);
        connection.connect();

我知道细节有点少,所以如果您需要更多信息,请告诉我,非常感谢您的任何意见!

【问题讨论】:

    标签: java http post request httpurlconnection


    【解决方案1】:

    您需要确保您还采用了name=valueall &lt;input type="hidden"&gt; 元素和一个&lt;input type="submit"&gt; 您想以编程方式在查询字符串中“按下”。该按钮只有一个名称,但无论如何,您都需要传递它。这样服务器端可以区分是否按下了按钮,如果按下了,是哪个。

    此外,如果表单需要会话(它可能使用基于请求的令牌),那么您还需要自己维护 cookie。检查并从第一个响应的头部获取Set-Cookie,并将其设置为后续请求的Cookie头部。

    如需更简单、更简洁的 HTTP/表单处理,请考虑使用 Apache HttpComponents Client

    另请参阅:

    【讨论】:

    • 澄清......为了让我的 POST 正常工作,我需要为每个输入(例如 qryStr)提供一个名称-值对,即使值是空的?另外,名称-值对如何用于提交按钮?
    • 是的。这也是一个体面的网络浏览器所做的。提交按钮还有一个namevalue 属性。您还需要发送它(就像您对每个其他输入元素所做的那样)。在您的情况下,按钮中省略了 value 属性,但无论如何您都需要发送 name 。只需将SUBMIT= 附加到查询字符串即可表明您已“按下”按钮。另请参阅给定的链接。它还包含很多提示和代码示例。
    • @Jon:既然你似乎已经改变了接受的答案,我很好奇问题的确切原因。还是两者兼而有之?在获得响应之前,您正确地刷新了输出。无需关闭即可获得响应。更重要的是,默认的HttpURLConnection 实现在发送请求之前已经隐式刷新了输出。
    • 我做错了很多...实际上我只需要正确监视浏览器中发生的事情,这就是为什么我将 ZZ 的答案设置为正确的原因。但是,我确实最终切换到了 HttpClient,并且您确实提供了更多有用的信息...再次更改答案...
    • 如果 中没有 name 字段,在 name=value 中添加什么
    【解决方案2】:

    您的代码在某些情况下可能会死锁。在读取输入之前,您应该关闭输出。如果不关闭流,服务器不知道您的请求已完成。

    如果您出于某种原因需要保持输出打开,您需要发送“Content-length”标头以通知服务器期望多少。

    参数必须正确编码。我一般都是这样放一张地图,然后序列化的,

                StringBuilder sb = new StringBuilder(baseUrl);
    
                for (Parameter p : parameters) {
                        if (sb.length() > 0)
                            sb.append('&');
                        try {
                                sb.append(URLEncoder.encode(p.name, "UTF-8"));
                                if (p.value != null) {
                                    sb.append('=');
                                    sb.append(URLEncoder.encode(p.value, "UTF-8"));
                                }
                        } catch (UnsupportedEncodingException e) {
                            // Not really possible, throw unchecked exception
                            throw new IllegalStateException("No UTF-8");
                        }
                }
    

    确定要发布哪些参数的最佳方法是在浏览器中捕获发布的跟踪,并查看浏览器如何执行此操作。 FireBug/DebugBar 是你的朋友。

    【讨论】:

      猜你喜欢
      • 2018-09-28
      • 2011-02-03
      • 1970-01-01
      • 2013-10-13
      • 1970-01-01
      • 2020-04-04
      • 2023-04-06
      • 2017-08-01
      • 1970-01-01
      相关资源
      最近更新 更多