Frage

Eine der Aktionen meiner JPF Controller erstellt eine PDF-Datei und ich würde diese Datei gerne an den Benutzer zurück, damit er sie herunterladen kann.

Ist es möglich, das zu tun, oder bin ich gezwungen, die Datei irgendwo und habe meine Aktion nach vorne einen Link zu dieser Datei zu schreiben? Beachten Sie, dass ich das so weit wie möglich zu vermeiden, möchte aus Sicherheitsgründen und weil ich habe keine Möglichkeit zu wissen, wann der Benutzer die Datei heruntergeladen hat, damit ich es löschen können.

Ich habe versucht, die HttpServletResponse zuzugreifen, aber nichts passiert:

getResponse().setContentLength(file.getSize());
getResponse().setContentType(file.getMimeType());
getResponse().setHeader("Content-Disposition", "attachment;filename=\"" + file.getTitle() + "\"");
getResponse().getOutputStream().write(file.getContent());
getResponse().flushBuffer();
War es hilfreich?

Lösung

Wir haben etwas ähnlich, nur Bilder anstelle eines PDF Rückkehr; obwohl sollte eine ähnliche Lösung sein, ich bin zu raten.

Auf einer JSP, haben wir einen IMG Tag, wo der src ist eingestellt auf:

<c:url value="/path/getImage.do?imageId=${imageID}" />

(Ich bin nicht alles zeigen, weil ich zu vereinfachen ich versuche.) In Ihrem Fall wäre es vielleicht einen Link, wo der href in ähnlicher Weise durchgeführt wird.

Dass getImage.do Karten in unseren JPF Controller, offensichtlich. Hier ist der Code aus dem JPF getImage() Verfahren, das ist der Teil, Sie versuchen zu arbeiten:

@Jpf.Action(forwards = {
    @Jpf.Forward(name = FWD_SUCCESS, navigateTo = Jpf.NavigateTo.currentPage),
    @Jpf.Forward(name = FWD_FAILURE, navigateTo = Jpf.NavigateTo.currentPage) })
public Forward getImage(final FormType pForm) throws Exception {
  final HttpServletRequest lRequest = getRequest();
  final HttpServletResponse lResponse = getResponse();
  final HttpSession lHttpSession = getSession();
  final String imageIdParam = lRequest.getParameter("imageId");

  final long header = lRequest.getDateHeader("If-Modified-Since");
  final long current = System.currentTimeMillis();

  if (header > 0 && current - header < MAX_AGE_IN_SECS * 1000) {
    lResponse.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
    return null;
  }

  try {
    if (imageIdParam == null) {
      throw new IllegalArgumentException("imageId is null.");
    }

    // Call to EJB, which is retrieving the image from
    // a separate back-end system
    final ImageType image = getImage(lHttpSession, Long
        .parseLong(imageIdParam));

    if (image == null) {
      lResponse.sendError(404, IMAGE_DOES_NOT_EXIST);
      return null;
    }

    lResponse.setContentType(image.getType());
    lResponse.addDateHeader("Last-Modified", current);
    // public: Allows authenticated responses to be cached.
    lResponse.setHeader("Cache-Control", "max-age=" + MAX_AGE_IN_SECS
        + ", public");
    lResponse.setHeader("Expires", null);
    lResponse.setHeader("Pragma", null);
    lResponse.getOutputStream().write(image.getContent());

  } catch (final IllegalArgumentException e) {
    LogHelper.error(this.getClass(), "Illegal argument.", e);
    lResponse.sendError(404, IMAGE_DOES_NOT_EXIST);
  } catch (final Exception e) {
    LogHelper.error(this.getClass(), "General exception.", e);
    lResponse.sendError(500);
  }
  return null;
}

Ich habe eigentlich sehr wenig von dieser Methode entfernt, da es dort sehr wenig ist, dass ich vor neugierigen Blicken verstecken müssen - der Code ziemlich allgemein ist, die sich mit Bildern, nicht mit der Geschäftslogik. (I einige der Datentypnamen geändert, aber keine große Sache.)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top