2011-01-07 17 views
41

Tôi đã viết mã tạo tệp Excel bằng cách sử dụng REST JAX-RS và tôi đã xác nhận rằng tệp Excel đã tạo nằm trong thư mục máy chủ GlassFish.Làm cách nào để đặt tiêu đề phản hồi trong JAX-RS để người dùng thấy cửa sổ bật lên tải xuống cho Excel?

Nhưng mục tiêu của tôi là khi người dùng nhấp vào nút (tạo Excel .xls), tôi muốn tải xuống popup để hiển thị yêu cầu người dùng lưu hoặc mở tệp .xls giống như bất kỳ dịch vụ web nào khác để tải xuống bất kỳ loại tệp.

Theo tìm kiếm của tôi, bước là:

  1. tạo Excel .xls (DONE)

  2. viết excel để dòng

  3. trong tập tin JAX-RS, thiết lập phản ứng tiêu đề cho một cái gì đó như,

    String fileName = "Blah_Report.xls"; response.setHeader ("Nội dung-Bố trí", "tệp đính kèm; tên tệp =" + tên tệp);

Câu hỏi của tôi là tôi đang làm tất cả điều này trong tệp JAX-RS và tôi không có đối tượng HttpServletResponse.

Theo câu trả lời từ Add Response Header to JAX-RS Webservice

Ông nói:

Bạn có thể tiêm một tham chiếu đến thực tế HttpServletResponse qua chú thích @Context trong webservice của bạn và sử dụng addHeader() vv để thêm tiêu đề của bạn.

tôi có thể không thực sự tìm những gì chính xác điều đó có nghĩa là không có mã mẫu ..

Trả lời

73

Bạn không cần HttpServletResponse để đặt tiêu đề cho phản hồi. Bạn có thể làm điều đó bằng cách sử dụng javax.ws.rs.core.Response. Chỉ cần chắc phương pháp của bạn để trở đáp ứng thay vì thực thể:

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

Nếu bạn vẫn muốn sử dụng HttpServletResponse bạn có thể làm cho nó một trong hai tiêm với một trong các trường lớp, hoặc sử dụng tài sản, hoặc tham số phương pháp:

@Path("/resource") 
class MyResource { 

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

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

@GarretWilson Tại sao không? Điều gì làm bạn bối rối? Đó là một tiêu đề đơn giản. – Tarlog

+0

Bởi vì một singleton 'MyResource' sẽ có' myMethod() 'được gọi bởi nhiều chủ đề cùng một lúc. Mỗi luồng sẽ có một phiên bản 'HttpServletResponse' khác nhau, nhưng biến thành viên' anotherServletResponse' đơn lẻ chỉ có thể chứa một giá trị duy nhất tại một thời điểm. Cách duy nhất này sẽ hoạt động là nếu 'anotherServletResponse' được tiêm một số proxy an toàn thread sử dụng một luồng cục bộ hoặc một số để xác định thực thể' HttpServletResponse' thực của luồng hiện tại. –

+0

Theo như tôi nhớ HttpServletRequestWrapper được tiêm; việc thực hiện của nó lấy HttpServletRequest thực từ TLS. Vì vậy, đoán của bạn là nhiều hơn hoặc ít hơn chính xác. – Tarlog

0

I figured thiết đáp ứng tiêu đề HTTP và dòng để hiển thị tải-popup trong trình duyệt thông qua servlet tiêu chuẩn. lưu ý: Tôi đang sử dụng Excella, excel API đầu ra.

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

không cần thiết lập Content-Lenght, nó được tính bằng cách nào đó trong nền tảng JavaEE ;-) –

Các vấn đề liên quan