2011-01-07 5 views
41

REST JAX-RSを使用してExcelファイルを生成するコードを作成し、生成されたExcelファイルがGlassFishサーバーディレクトリにあることを確認しました。JAX-RSでレスポンスヘッダーを設定して、Excel用のダウンロードポップアップを表示する方法は?

私の目標は、ユーザーが(.xlsを生成する)ボタンをクリックしたときに、ダウンロードするポップアップを、他のWebサービスと同じように.xlsファイルを保存するか開くかを尋ねるファイルの種類。私の検索によると、ステップは

されています:

  1. はExcelの.XLS(DONE)

  2. を生成するJAX-RSファイルに

  3. をストリーミングするためにExcelを書き、応答を設定のようなものにヘッダーを設定します。

    文字列fileName = "Blah_Report.xls"; response.setHeader( "Content-Disposition"、 "attachment; filename =" + fileName);

私の質問は、JAX-RSファイルでこれをすべて実行しているため、HttpServletResponseオブジェクトを使用できません。

Add Response Header to JAX-RS Webservice

からの回答によると、彼は言う:

あなたは、あなたのWebサービス に @Contextアノテーションを介した 実際のHttpServletResponseへの参照を注入してのaddHeaderを使用することができます()など。 ヘッダーを追加してください。

私は本当にそれが、サンプルコードなしで意味を正確に把握することはできません。..

答えて

73

レスポンスにヘッダーを設定するためにHttpServletResponseは必要ありません。これは、 javax.ws.rs.core.Responseを使用して行うことができます。ただ、実体の代わりにレスポンスを返すようにあなたの方法を作る:

return Response.ok(entity).header("Content-Disposition", "attachment; filename=" + fileName).build() 

をあなたはまだあなたはそれがいずれかのクラスのフィールドのいずれかに注入、またはプロパティを使用して、またはメソッドパラメータに取得することができHttpServletResponseのを使用する場合:

@Path("/resource") 
class MyResource { 

    // one way to get HttpServletResponse 
    @Context 
    private HttpServletResponse anotherServletResponse; 

    // another way 
    Response myMethod(@Context HttpServletResponse servletResponse) { 
     // ... code 
    } 
} 
+0

@GarretWilsonなぜですか?何があなたを混乱させますか?シンプルなヘッダーです。 – Tarlog

+0

シングルトンの 'MyResource'は複数のスレッドから同時に呼び出される' myMethod() 'を持つためです。各スレッドは 'HttpServletResponse'の別のインスタンスを持ちますが、シングルトン' anotherServletResponse'メンバ変数は一度に一つの値しか保持できません。これが動作する唯一の方法は、 'anotherServletResponse'に、ローカルのスレッドや現在のスレッドの実際の' HttpServletResponse'インスタンスを特定するスレッドを使用するスレッドセーフなプロキシを注入した場合です。 –

+0

私が覚えている限り、HttpServletRequestWrapperは注入されています。その実装は、TLSから実際のHttpServletRequestを受け取ります。だからあなたの推測は多かれ少なかれ正しいです。 – Tarlog

0

私は、HTTPレスポンスヘッダを設定し、標準のサーブレット経由でブラウザにダウンロード-ポップアップを表示するためにストリーミングするために考え出しました。注:Excellaを使用しています。出力APIが優れています。

package local.test.servlet; 

import java.io.IOException; 
import java.net.URL; 
import java.net.URLDecoder; 
import javax.servlet.ServletException; 
import javax.servlet.annotation.WebServlet; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import local.test.jaxrs.ExcellaTestResource; 
import org.apache.poi.ss.usermodel.Workbook; 
import org.bbreak.excella.core.BookData; 
import org.bbreak.excella.core.exception.ExportException; 
import org.bbreak.excella.reports.exporter.ExcelExporter; 
import org.bbreak.excella.reports.exporter.ReportBookExporter; 
import org.bbreak.excella.reports.model.ConvertConfiguration; 
import org.bbreak.excella.reports.model.ReportBook; 
import org.bbreak.excella.reports.model.ReportSheet; 
import org.bbreak.excella.reports.processor.ReportProcessor; 

@WebServlet(name="ExcelServlet", urlPatterns={"/ExcelServlet"}) 
public class ExcelServlet extends HttpServlet { 

    @Override 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 


     try { 

      URL templateFileUrl = ExcellaTestResource.class.getResource("myTemplate.xls"); 
      // /C:/Users/m-hugohugo/Documents/NetBeansProjects/KogaAlpha/build/web/WEB-INF/classes/local/test/jaxrs/myTemplate.xls 
      System.out.println(templateFileUrl.getPath()); 
      String templateFilePath = URLDecoder.decode(templateFileUrl.getPath(), "UTF-8"); 
      String outputFileDir = "MasatoExcelHorizontalOutput"; 

      ReportProcessor reportProcessor = new ReportProcessor(); 
      ReportBook outputBook = new ReportBook(templateFilePath, outputFileDir, ExcelExporter.FORMAT_TYPE); 

      ReportSheet outputSheet = new ReportSheet("MySheet"); 
      outputBook.addReportSheet(outputSheet); 

      reportProcessor.addReportBookExporter(new OutputStreamExporter(response)); 
      System.out.println("wtf???"); 
      reportProcessor.process(outputBook); 


      System.out.println("done!!"); 
     } 
     catch(Exception e) { 
      System.out.println(e); 
     } 

    } //end doGet() 

    @Override 
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 

    } 

}//end class 



class OutputStreamExporter extends ReportBookExporter { 

    private HttpServletResponse response; 

    public OutputStreamExporter(HttpServletResponse response) { 
     this.response = response; 
    } 

    @Override 
    public String getExtention() { 
     return null; 
    } 

    @Override 
    public String getFormatType() { 
     return ExcelExporter.FORMAT_TYPE; 
    } 

    @Override 
    public void output(Workbook book, BookData bookdata, ConvertConfiguration configuration) throws ExportException { 

     System.out.println(book.getFirstVisibleTab()); 
     System.out.println(book.getSheetName(0)); 

     //TODO write to stream 
     try { 
      response.setContentType("application/vnd.ms-excel"); 
      response.setHeader("Content-Disposition", "attachment; filename=masatoExample.xls"); 
      book.write(response.getOutputStream()); 
      response.getOutputStream().close(); 
      System.out.println("booya!!"); 
     } 
     catch(Exception e) { 
      System.out.println(e); 
     } 
    } 
}//end class 
14
@Context ServletContext ctx; 
@Context private HttpServletResponse response; 

@GET 
@Produces(MediaType.APPLICATION_OCTET_STREAM) 
@Path("/download/{filename}") 
public StreamingOutput download(@PathParam("filename") String fileName) throws Exception { 
    final File file = new File(ctx.getInitParameter("file_save_directory") + "/", fileName); 
    response.setHeader("Content-Length", String.valueOf(file.length())); 
    response.setHeader("Content-Disposition", "attachment; filename=\""+ file.getName() + "\""); 
    return new StreamingOutput() { 
     @Override 
     public void write(OutputStream output) throws IOException, 
       WebApplicationException { 
      Utils.writeBuffer(new BufferedInputStream(new FileInputStream(file)), new BufferedOutputStream(output)); 
     } 
    }; 
} 
+0

Content-Lenghを設定する必要はありませんが、JavaEEプラットフォームで何とか計算されます;-) –

関連する問題