2011-01-07 1 views
41

Ich schrieb Code, der Excel-Datei mit REST JAX-RS generieren und ich bestätigte, dass die generierte Excel-Datei im GlassFish-Server-Verzeichnis ist.Wie setzt man den Antwort-Header in JAX-RS so, dass der Benutzer das Popup-Fenster zum Herunterladen für Excel sieht?

Aber mein Ziel ist, wenn Benutzer auf die Schaltfläche klicken (die Excel .xls generieren), ich möchte Download-Popup anzeigen Benutzer fragen, ob die .xls-Datei zu speichern oder zu öffnen, genau wie alle anderen Web-Dienste für das Herunterladen von Art der Dateien.

Nach meiner Suche, der Schritt ist:

  1. erzeugen Excel .xls (DONE)

  2. schreiben die Excel

  3. in JAX-RS-Datei, setzen Antwort zu streamen Header zu etwas wie,

    String fileName = "Blah_Report.xls"; response.setHeader ("Content-Disposition", "Anhang; Dateiname =" + Dateiname);

Meine Frage ist, ich bin alles in JAX-RS-Datei zu tun, und ich habe nicht HttpServletResponse Objekt zur Verfügung.

Nach der Antwort von Add Response Header to JAX-RS Webservice

Er sagt:

Sie einen Verweis auf die tatsächlichen HttpServletResponse über die @Context Anmerkung in Ihrem webservice injizieren können und verwenden addHeader() usw. Fügen Sie Ihre Kopfzeile hinzu.

Ich kann nicht wirklich Figur, was genau das bedeutet, ohne Codebeispiel ..

Antwort

73

Sie benötigen keine HttpServletResponse, um eine Kopfzeile für die Antwort festzulegen. Sie können es mit javax.ws.rs.core.Response tun. So stellen Sie Ihre Methode Reaktion statt Einheit zurückzukehren:

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

Wenn Sie noch HttpServletResponse verwenden möchten Sie es entweder zu einer der Klassenfelder injiziert bekommen können, oder unter Verwendung von Eigentum oder Verfahrensparameter:

@Path("/resource") 
class MyResource { 

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

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

@GarretWilson Warum nicht? Was verwirrt dich? Es ist ein einfacher Header. – Tarlog

+0

Weil ein Singleton 'MyResource'' myMethod() 'gleichzeitig von mehreren Threads aufrufen würde. Jeder Thread würde eine andere Instanz von "HttpServletResponse" haben, doch die Singleton-Variablen "anotherServletResponse" kann immer nur einen einzelnen Wert enthalten. Der einzige Weg, wie dies funktioniert, ist, wenn 'anotherServletResponse' mit einem thread-sicheren Proxy injiziert wurde, der einen lokalen Thread oder ähnliches verwendet, um die tatsächliche 'HttpServletResponse'-Instanz des aktuellen Threads zu bestimmen. –

+0

Soweit ich mich erinnere, wird HttpServletRequestWrapper injiziert; Seine Implementierung nimmt den echten HttpServletRequest vom TLS. Deine Schätzung ist mehr oder weniger korrekt. – Tarlog

0

Ich dachte HTTP-Antwort-Header zu setzen und Strom über Standard-Servlet in Browser Download-Popup angezeigt werden soll. Hinweis: Ich verwende Excella, Excel-Ausgabe-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

keine Notwendigkeit, Content-Lenght einzurichten, es wird irgendwie in JavaEE-Plattform berechnet ;-) –

Verwandte Themen