web-dev-qa-db-fra.com

Comment définir l'en-tête de réponse dans JAX-RS pour que l'utilisateur voit une fenêtre de téléchargement pour Excel?

J'ai écrit du code qui génère un fichier Excel en utilisant REST JAX-RS et j'ai confirmé que le fichier Excel généré se trouve dans le répertoire du serveur GlassFish.

Mais mon objectif est lorsque l'utilisateur clique sur le bouton (qui génère Excel .xls), je souhaite que la fenêtre de téléchargement s'affiche pour demander à l'utilisateur s'il doit enregistrer ou ouvrir le fichier .xls comme tout autre service Web pour télécharger tout type de fichiers.

Selon ma recherche, l'étape est:

  1. générer Excel .xls (TERMINÉ)

  2. écrire Excel pour diffuser

  3. dans le fichier JAX-RS, définissez l'en-tête de réponse sur quelque chose comme,

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

Ma question est que je fais tout cela dans un fichier JAX-RS et je n'ai pas d'objet HttpServletResponse disponible.

Selon la réponse de Ajouter un en-tête de réponse au service Web JAX-RS

Il dit:

Vous pouvez injecter une référence à la HttpServletResponse réelle via l'annotation @Context dans votre webservice et utiliser addHeader () etc. pour ajouter votre en-tête.

Je ne peux pas vraiment comprendre ce que cela signifie sans exemple de code ..

47
masato-san

Vous n'avez pas besoin de HttpServletResponse pour définir un en-tête sur la réponse. Vous pouvez le faire en utilisant javax.ws.rs.core.Response. Faites simplement votre méthode pour renvoyer Response au lieu d'entité:

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

Si vous souhaitez toujours utiliser HttpServletResponse, vous pouvez l'obtenir soit injecté dans l'un des champs de classe, soit en utilisant la propriété, soit en paramètre de méthode:

@Path("/resource")
class MyResource {

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

  // another way
  Response myMethod(@Context HttpServletResponse servletResponse) {
      // ... code
  }
}
85
Tarlog
@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));
        }
    };
}
16
Jay

J'ai pensé à définir l'en-tête de réponse HTTP et le flux pour afficher la fenêtre de téléchargement dans le navigateur via un servlet standard. remarque: j'utilise Excella, l'API de sortie Excel.

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
1
masato-san