2011-08-25 132 views
1

我试图使用套接字从Java客户端发布一些数据。它会与运行php代码的localhost进行交流,它只是将发送给它的后续参数吐出。Http Post不发布数据

这里是Java客户端:

public static void main(String[] args) throws Exception { 

     Socket socket = new Socket("localhost", 8888); 
     String reqStr = "testString"; 

     String urlParameters = URLEncoder.encode("myparam="+reqStr, "UTF-8"); 
     System.out.println("Params: " + urlParameters); 

     try { 
      Writer out = new OutputStreamWriter(socket.getOutputStream(), "UTF-8"); 
      out.write("POST /post3.php HTTP/1.1\r\n"); 
      out.write("Host: localhost:8888\r\n"); 
      out.write("Content-Length: " + Integer.toString(urlParameters.getBytes().length) + "\r\n"); 
      out.write("Content-Type: text/html\r\n\n"); 
      out.write(urlParameters); 
      out.write("\r\n"); 
      out.flush(); 

      InputStream inputstream = socket.getInputStream(); 
      InputStreamReader inputstreamreader = new InputStreamReader(inputstream); 
      BufferedReader bufferedreader = new BufferedReader(inputstreamreader); 

      String string = null; 
      while ((string = bufferedreader.readLine()) != null) { 
       System.out.println("Received " + string); 
      } 

     } catch(Exception e) { 
      e.printStackTrace(); 
     } finally { 
     socket.close(); 
     } 
} 

这是post3.php的样子:

<?php 

$post = $_REQUEST; 

echo print_r($post, true); 
?> 

我希望看到一个数组(myparams => “的TestString”)作为响应。但它没有通过发布参数到服务器。 这里输出:

Received HTTP/1.1 200 OK 
Received Date: Thu, 25 Aug 2011 20:25:56 GMT 
Received Server: Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8r DAV/2 PHP/5.3.6 
Received X-Powered-By: PHP/5.3.6 
Received Content-Length: 10 
Received Content-Type: text/html 
Received 
Received Array 
Received (
Received) 

只是一个FYI,这个设置适用于GET请求。

任何想法这里发生了什么?

+1

只是想知道...有你不使用任何理由[了HTTPClient](http://hc.apache.org/httpcomponents-client-ga/ index.html的)? – chesles

+1

或[Resty](http://beders.github.com/Resty/Resty/Overview.html)。 –

+0

@ chesles-我正在通过SSL发送数据。 HttpClient-4的文档对设置定制的SSLSocketFactory并不是很有帮助。所以,在我用头部计算出用HttpClient4定制SSLSocketFactory之前,我正在试用普通套接字上的东西。 – bianca

回答

1

正如Jochen和chesles正确指出的那样,您正在使用错误的Content-Type:标题 - 它的确应该是application/x-www-form-urlencoded。然而,还有其他几个问题...

  • 最后一个标题应与标题和正文之间的空行分开。这应该是一个完整的CRLF(\r\n),在你的代码中它只是一个新行(\n)。这是一个违反协议的行为,我有点惊讶,你并没有从服务器获得400 Bad Request,尽管Apache在这方面可以相当宽容。
  • 您应该指定Connection: close以确保您不会在开放套接字中闲置,服务器会在请求完成后立即关闭连接。
  • 最终的CRLF序列不是必需的。 PHP是足够智能的,可以自行整理,但其他服务器语言和实现可能不是...

如果您使用的任何标准化协议处于原始状态,您应该始终以至少扫描超过the RFC

另外,请学会secure your Apache installs ...

+0

非常感谢戴夫和凯瑟斯花时间帮助我。我需要访问第三方服务器,并要求我在发送请求时发送键值对中的xml请求并使用text/html Content-Type。感谢您澄清我的理解。 – bianca

0

它看起来像你试图以application/x-www-form-urlencoded格式发送数据,但是你将Content-Type设置为text/html。

+0

如何在Content-Type文本/ html中发送数据?任何指针? – bianca

+0

@bianca通过发送一些HTML到服务器...但你为什么要这样做? – DaveRandom

+0

@dave,实际的服务器接受text/html Content-Type。有没有办法以text/html的方式发送数据,而不是application/x-www-form-urlencoded? – bianca

0

使用

out.write("Content-Type: application/x-www-form-urlencoded\n\n"); 

代替。作为this page状态:

,因为他们知道什么样的网络服务器数据的多少字节期望,并通过MIME类型识别出的内容长度和Content-Type标头是关键。

用于发送表格数据,即格式为key=value&key2=value2的数据使用application/x-www-form-urlencodedvalue是否包含HTML,XML或其他数据无关紧要;服务器会为您解释它,您将能够像往常一样在PHP端的$_POST$_REQUEST阵列中检索数据。

或者,您也可以通过读取特殊文件php://input发送您的数据作为原始的HTML,XML等使用适当的Content-Type头,但你必须要retrieve the data manually in PHP

<?php 
echo file_get_contents("php://input"); 
?> 

顺便说一句,如果你使用这个用于任何足够复杂的事情,我强烈建议使用一个HTTP客户端库,如HTTPClient

+0

我的示例代码适用于此更改,但实际服务器支持text/html Content-Type。有没有办法以text/html的方式发送数据,而不是application/x-www-form-urlencoded? – bianca

+0

@bianca你究竟想要发送给服务器?为什么你需要发送HTML到服务器?正在尝试上传文件? – DaveRandom

+0

@dave,我想将XML发送到服务器。就像这样:testXml = <?xml version =“1.0”encoding =“UTF-8”?> testData – bianca