2009-06-25 20 views
0

いくつかのリクエストパラメータを受け取り、XMLデータを返すリモートサービスを呼び出し、XSL経由でデータを変換して結果を返すことによって、AJAXリクエストに応答するstruts2アクションを取得しましたストリーム結果を介したXHTML。応答は、与えられたパラメータによって異なります。ここでstruts2アクションを使用した複数の同時AJAXリクエストの処理

を取り出し原料の束を持つアクションクラスです:

public class ServiceHandler extends ActionSupport { 
    private ByteArrayInputStream inputStream; 

    public String execute(){ 

     String response = ""; 

     // Get request parameters 
     // Make a request to a remote server via an http connection 
     // Transform result via XSL 

     //uses dom4j for XML/XSL stuff 
     //this should never be empty 
     response = resultDoc.asXML(); 

     inputStream = new ByteArrayInputStream(response.getBytes()); 
     return "success"; 
    } 

    public ByteArrayInputStream getInputStream(){ 
     return inputStream; 
    } 
} 

そして、ここでは重要なstruts.xmlビットです:

<action name="sh" class="ServiceHandler"> 
    <result name="success" type="stream"> 
     <param name="contentType">text/html</param> 
     <param name="contentDisposition">inline;filename="response.html"</param> 
     <param name="bufferSize">1024</param> 
     <param name="allowCaching">false</param> 
    </result> 
</action> 

私の問題は、私は複数の要求を持っている場合ということです同時に、ServiceHandlerアクションを呼び出すすべての応答、場合によっては応答が完全に空白(何も起こらないはずです)、応答が開始時または終了時に何らかのランダムな量で途切れることがあります。 Aが間違った応答を受信した場合JAXリクエスタ。

私はこれがスレッドの安全性の問題であることを知っています。すべての重要な変数定義をexecute()メソッドに移してインスタンス変数ではない(したがってすべてが共有する)ようにしました。インスタンス変数である唯一興味深い変数はinputStreamです。私はそれを私の問題の原因として考えています。

inputStream変数をスレッドセーフにする方法はありますか?または私は見ていない別の解決策はありますか?

答えて

0

正しい方向に私を導いてくれてありがとうHenningありがとう。私は、レスポンス出力ストリームに直接書くことは考えていませんでした。なぜなら、それはstruts2のドキュメントのどこにも言及されていないからです。

応答を出力ストリームに直接書き込む利点は、inputStreamのインスタンスオブジェクトを作成する必要がないことです。これにより、すべてのデータが他のスレッドから安全なexecute()メソッドに保持されます。

ここでは、出力ストリームに直接書き込みを行い、null結果を返す変更されたアクションクラスを示します。

import javax.servlet.http.HttpServletResponse; 
import org.apache.struts2.ServletActionContext; 

public class ServiceHandler extends ActionSupport { 
    public String execute(){ 

     String response = ""; 

     // Get request parameters 
     // Make a request to a remote server via an http connection 
     // Transform result via XSL 

     //uses dom4j for XML/XSL stuff 
     //this should never be empty 
     response = resultDoc.asXML(); 

     HttpServletResponse httpResponse = ServletActionContext.getResponse(); 
     try{ 
      httpResponse.getOutputStream().print(response); 
     } 
     catch(IOException e){ 
      return "failure"; 
     } 

     return null; 
    } 
} 

これは私が持っていた問題を修正したようです。

0

私はStruts 1に精通していますが、DonwloadActionを見てください。または、単純なStrutsアクションを使用し、結果を直接レスポンスオブジェクトに書き込み、前方にnullを返します。

0

私はStruts 2にはまったく参加していませんが、実際に「成功」​​の結果を返して出力に直接書き込む必要がない場合は、ThreadLocalを使用して現在のスレッドに対してローカルなストリーム。 (パターンの詳細については、スレッドローカルストレージのWikipedia articleも参照してください。)

+0

私は「成功」を返す必要はなく、できる限り行えない、またはできない限り、struts2によって制約されています。インスタンス変数を使用せずに直接出力する方法を見つけることができたら、それを行います。 –

+0

これを行う方法が見つかりましたが、直接問題が解決したようです。 –

関連する問題