2016-11-30 5 views
1

私はRESTfulなサービスのクライアント側で、ユーザーがファイルをダウンロードできるように取り組んでいます。私はサーバーサイドコードにアクセスできます。JerseyでStruts 2フレームワークを介してファイルを入力ストリームとしてダウンロードしますか?

クライアントはStruts 2の下にあり、いくつかのxmlを含むPOSTリクエストを送信し、サーバー(Spring下)はそのXMLを処理した後にzipファイルのバイト配列表現を生成します。私の問題は、バイト配列をInputStreamのように転送する方法です。これはStruts 2のダウンロードに必要です。

クライアントは、Strutsの2使用であり、ここでstruts.xml内の構成は、ジャージーを使用してファイル

<action name="getResponseMessage" 
     class="DownloadAction" 
     method="retrieveDownloadableMessage"> 
     <interceptor-ref name="logger" /> 
     <interceptor-ref name="defaultStack" /> 
     <result name="success" type="stream"> 
      <param name="contentType">application/octet-stream</param> 
      <param name="inputName">inputStream</param> 
      <param name="contentDisposition">attachment;filename="${bundleName}"</param> 
      <param name="bufferSize">1024</param> 
     </result> 
</action> 

をダウンロードするためとJavaアクションクラスである(あるHTTPステータスチェックとフィールドのための適切なゲッター、どのI簡略化のため省略):。

public class DownloadAction extends ActionSupport { 

    private InputStream inputStream; 
    private String bundleName; 

    public String retrieveDownloadableMessage() throws IOException { 

     ClientConfig config = new DefaultClientConfig(); 
     Client client = Client.create(config); 

     URI restfulURI = getRestfulURI(); 
     WebResource resource = client.resource(restfulURI); 

     inputStream = resource.accept(MediaType.APPLICATION_OCTET_STREAM).post(InputStream.class, someXML); 

     bundleName = "response.zip"; 

     return SUCCESS; 
    } 
} 

RESTサーバー側のコードのバックボーン:

@POST 
@Produces(MediaType.APPLICATION_OCTET_STREAM) 
@Consumes({ MediaType.APPLICATION_XML, MediaType.TEXT_XML }) 
public Response getPtrXml(Source source) throws IOException { 

    byte[] myByteArray = generateByteArr(source); // I cannot modify this method. 

    ByteArrayInputStream byteInputStream = new ByteArrayInputStream(myByteArray); 

    return Response.ok(byteInputStream, MediaType.APPLICATION_OCTET_STREAM).build(); 

} 

クライアント側のコードを実行するこのようにコンソールに出力が表示されます。クライアントに何も送信されていないようです。何が問題なの?

Streaming result [inputStream] type=[application/octet-stream] length=[0] content-disposition=[attachment;filename="${packagePtrName}"] charset=[null] 

E WLTC0017E: Resources rolled back due to setRollbackOnly() being called. 

E com.ibm.ws.webcontainer.webapp.WebApp logServletError SRVE0293E: [Servlet Error]-[ServletNameNotFound]: java.lang.IllegalStateException: Response already committed. 

更新:Strutsの2は黙って私が返されるByteArrayInputStreamを受け入れるようにFileオブジェクトを使用している場合、私は見つけるtempフォルダ

にファイルを保存し、その後のStruts 2は何とかファイルを保存します(まさにIユーザにダウンロードダイアログボックスを開くことなく、ローカルの一時フォルダに移動することができます。どのようにそれを掘る考え?

File fileToDownload = resource.accept(MediaType.APPLICATION_OCTET_STREAM).post(File.class, someXML); 

inputStream = new FileInputStream(fileToDownload); 

答えて

1

クライアントの応答を返す前に、ステータスコードを確認する必要があります。あなたがそれをしなかったので、あなたがそれを読むまで入力ストリームを返すことはできません。

if (response.getStatus() != 200) { 
    throw new RuntimeException("Failed : HTTP error code : " 
    + response.getStatus()); 
} 

また、あなたがbundleNameの公開ゲッターを提供しなかった、あなたは${bundleName}ファイル名を得た応答

inputStream = response.getEntityInputStream(); 
if (inputStream != null) { 
    //read it to make sure the data is available 

からの入力ストリームを取得することができます。

+0

バイト配列自体を応答として送信することはできますか?構文は何ですか?ところで、私は実際のクラスでbundleNameのゲッターを持っています。 – dunfa

+0

いくつかのエラーメッセージが更新されました。なぜ私がレスポンスを修正しようとしていると報告しているのか分かりません。 – dunfa

+0

なぜ私は私の例でそれを使用していません。 –

関連する問題