2011-08-10 28 views
1

さまざまなRSSフィードを解析し、その情報をリモートサーバーに送信するアプリケーションが必要です。情報は、HTTP経由でxml形式で送信されます。最初は自分のサーバーにこのアプリケーションをデプロイしようとしましたので、Javaヒントでthis tutorialに示されているメソッドを使用してxmlを送信します。ここでは例から複製された私のコードは次のとおりです。HTTP経由で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に移行することに決めました。私たちが知っているように、それについての一つのことは、すべての図書館がその環境で許可されているわけではないということです。だから私は、以下のように(ただし正確なURLどこで見つけることができません)ExampleDepot.comに示す別の方法を試してください:

第2の方法

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(); 
     } 
    } 

しかし第2の方法は、動作しないと次のエラー(私はリモートホストにXMLを解析するためにSimpleXMLElement(PHP)オブジェクトを使用)を与える:

ここError message from remote server

は、リモートサーバーからのPHPコードです(ここでは、私はちょうどシムをしたいですpleXMLElementは、Eclipse IDEは、1バイトのUTFの無効バイト1」のエラーがあります示しているので、私は(この問題の原因は故障xmlファイルであると思っ

$xml = new SimpleXMLElement('php://input', NULL, TRUE); 
    foreach ($xml -> attributes() as $name => $val){ 
    echo "[".$name."] = ".$val."\n"; 
    } 

)今のところは何も他の空想をすることなく、XMLをパースします-8配列 ")。その後、私は最初のメソッドに同じ正確な入力XMLファイルを使用しますが、それでも完全に動作します。

私は2番目の方法に調整する必要がありますか?または、xmlファイルをリモートサーバーに送信するために使用できる他の方法はありますか?他の詳細を追加する必要があるかどうかを教えてください。ご協力いただきありがとうございます。


注:この問題は、実際にコメントに記載されている解決策を使用して解決しました。私は答えに示唆されたアプローチを使用しませんでしたが、それらの答えはかなり有用です。だから、私は与えられた答えから最善の答えを選んでいない。それにもかかわらず、私はあなたのすべての助けに感謝し、私のupvoteに値する。乾杯!

+2

入力ファイルの大きさ(出力xml)。 2番目の解決策では、ファイルの最初の10240バイトだけを読み込みます。また、印刷ストリームをフラッシュする代わりに、出力ストリームを閉じる必要があります。 – beny23

+1

beny23のように、XML全体を読んでいるわけではありません。その 'if'文を' while'ループに変換し、ループからネットワークコードを移動します。 'PrintWriter'も閉じます。 – asgs

+0

@ beny23とasgs私はちょうど両方のあなたの助言に従って、かなりのものを修正します(まだ別のものを残していますが、上記のエラーはなくなっています)。私はストリームの限られた量だけを読んでいたことに気付かなかった。だからあなたの両方のためにupvote!ありがとう! – vandershraaf

答えて

1

コンテンツタイプをmultipart/form-dataに変更する必要があると思います。詳細はSee an already answered questionをご覧ください。ファイルアップロードはこの例の最後で説明されています

+0

これはおそらく答えが短すぎるかもしれませんが、素晴らしい参照を与えるためのアップヴォート – vandershraaf

0

テキストファイルを読んでいる場合を除き、決してファイルを文字として読み取らないでください。 xml はテキストではありません、バイナリ形式です。通常のInputStreamとbyte []を使用してファイルをコピーします。

また、@ beny23は彼のコメントで提案したように、ループを使用してストリームをコピーするようにしてください。read()(バッファが十分に大きい場合でも、InputStreamによってすべてのバイト1回の呼び出しで、FileInputStreamの場合でも)。

+0

もちろん、XMLはテキストです。どのようなXMLを考えていますか? –

+0

うわー、私はdownvotesが大好き!真剣に、XML形式でお読みください。コードが修正され、私の答えが正しいと分かったら、あなたのdownvotesを削除してください。 @ライアン・スチュワート - あなたが理解していないものにコメントを投稿する前に、バックグラウンドで読んでください。 – jtahlborn

+0

すべての人に混乱しています。はい、xmlはテキストのように見えます。しかし、XML文書の解析に関するすべての詳細を理解していれば、XML文書を文字通りに盲目的に変換するだけで、文書を破損させることは確実です。 – jtahlborn

1

最初の回答が示すように、InputStreamでファイルを読み込みます。バイトから文字への変換は、不要で、エラーの原因となります。また、入力ファイルが実際にISO-8859-1エンコーディングを使用していることを確認してください。

UPDATE:FileReaderを使用している場合

、あなたはデフォルトのエンコーディングを受け入れる(すなわちbytesからcharsを作成する方法)。このエンコーディングは、入力ファイルに使用されているエンコーディングと一致する必要があります。そうでない場合は、結果が壊れてしまう大きなリスクがあります。デフォルトのJavaエンコーディングはプラットフォームによって異なりますので、一般的にはそれに依存することはお勧めできません。

2番目の例では、ファイルを文字として読み取る理由はありません。なぜなら、それはバイトとしてワイヤで送信されるからです。バイトストリームを使用すると、エンコードの問題(コンテンツタイプヘッダーの情報は別として)も回避されます。

+0

これについてもっと説明できますか? – vandershraaf

関連する問題