我想要一个解析各种RSS源并将信息发送到远程服务器的应用程序。信息以xml格式通过http发送。起初我尝试在我自己的服务器上部署这个应用程序,所以我使用Java Tips的this tutorial中显示的方法发送xml。这是我从代码中复制的代码:
第一种方法
String strURL = "http://localhost/readme/readme_xml";
String strXMLFilename = "output.xml";
File input = new File(strXMLFilename);
PostMethod post = new PostMethod(strURL);
post.setRequestEntity(new InputStreamRequestEntity(
new FileInputStream(input), input.length()));
post.setRequestHeader(
"Content-type", "text/xml; charset=ISO-8859-1");
HttpClient httpclient = new HttpClient();
try {
int result = httpclient.executeMethod(post);
System.out.println("Response status code: " + result);
System.out.println("Response body: ");
System.out.println(post.getResponseBodyAsString());
} finally {
post.releaseConnection();
}
这非常有效(我甚至使用localhost之外的远程服务器进行了测试)。然后,不知何故,我无法使用自己的服务器来部署此应用程序,因此我决定迁移到Google Apps Engine。正如我们所知,关于它的一件事是,并非所有库都被允许进入环境。所以我尝试在ExampleDepot.com中显示的另一种方法(我找不到确切的网址),如下所示:
第二种方法
try {
/* fill up this url with the remote server url */
URL url = new URL("http://localhost/readme/readme_xml");
FileReader fr = new FileReader("output.xml");
char[] buffer = new char[1024*10];
int len = 0;
if ((len = fr.read(buffer)) != -1){
/* send http request to remote server */
URLConnection conn = url.openConnection();
conn.setRequestProperty("Content-Type","text/xml;charset=ISO-8859-1"); /* need to specify the content type */
conn.setDoOutput(true);
conn.setDoOutput(true);
PrintWriter pw = new PrintWriter(conn.getOutputStream());
pw.write(buffer, 0, len);
pw.flush();
/* receive response from remote server*/
BufferedReader bf = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String input = null;
while ((input = bf.readLine()) != null){
System.out.println(input);
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
第二种方法虽然不起作用并且给出以下错误(我使用SimpleXMLElement(php)对象来解析远程主机中的xml):
Error message from remote server
这是来自远程服务器的php代码(在这里,我只是希望SimpleXMLElement解析xml而不做任何其他想象的事情)
$xml = new SimpleXMLElement('php://input', NULL, TRUE);
foreach ($xml -> attributes() as $name => $val){
echo "[".$name."] = ".$val."\n";
}
我认为这个问题的原因是故障xml文件(因为eclipse IDE指示存在“1字节utf-8序列的无效字节1”的错误)。然后我使用相同的输入xml文件到第一个方法,但它仍然完美。
那么我需要对第二种方法进行调整吗?或者我可以使用任何其他方法将xml文件发送到远程服务器?如果我需要添加其他一些细节,请告诉我。谢谢你的帮助。
注意:我实际上是通过使用评论中给出的解决方案解决了这个问题。我没有使用答案中建议的方法,即使这些答案非常有用。所以,我没有从给出的答案中选出最佳答案。尽管如此,我仍然感谢你的所有帮助,因此值得我的支持。干杯!
答案 0 :(得分:1)
我猜您需要将内容类型更改为multipart / form-data。 See an already answered question详细说明。文件上传将在本示例的底部讨论
答案 1 :(得分:1)
作为第一个答案建议,我会用InputStream读取文件。从字节转换为char并再次返回是不必要的并且是错误的来源。另外,请验证输入文件是否确实使用了ISO-8859-1编码。
更新:
使用FileReader
时,您接受默认编码(即如何从chars
制作bytes
)。此编码必须与用于输入文件的编码匹配,否则会导致结果损坏的风险很大。对于不同的平台,默认的Java编码是不同的,因此依赖它通常不是一个好主意。
在你的第二个例子中,没有理由将文件作为字符读取,因为无论如何它将作为字节在线路上发送。一直使用字节流也避免了编码问题(除了内容类型标题中的信息)。
答案 2 :(得分:0)
除非您正在阅读文本文件,否则永远不会将文件读取为字符。 xml 不是文本,它是二进制格式。使用普通的InputStreams和byte [] s复制文件。
另外,正如@ beny23在他的评论中所建议的,确保你总是使用循环复制流,而不是单个read()
(即使你的缓冲区足够大,也不能保证InputStream会给你一次调用中的所有字节,即使对于FileInputStream也是如此。