Execute backing bean action on load?

陌路散爱 提交于 2019-11-28 20:52:03

You can also solve this in JSF 2.0 using component system events, specifically the PreRenderViewEvent.

Just create a download view (/download.xhtml) that fires a download listener before render.

<?xml version="1.0" encoding="UTF-8"?>
<f:view
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core">
    <f:event type="preRenderView" listener="#{reportBean.download}"/>
</f:view>

Then, in your report bean (defined using JSR-299), you push the file and mark the response as complete.

public @Named @RequestScoped class ReportBean {

   public void download() throws Exception {
      FacesContext ctx = FacesContext.getCurrentInstance();
      pushFile(
           ctx.getExternalContext(),
           "/path/to/a/pdf/file.pdf",
           "file.pdf"
      ); 
      ctx.responseComplete();
   }

   private void pushFile(ExternalContext extCtx,
         String fileName, String displayName) throws IOException {
      File f = new File(fileName);
      int length = 0; 
      OutputStream os = extCtx.getResponseOutputStream();
      String mimetype = extCtx.getMimeType(fileName);

      extCtx.setResponseContentType(
         (mimetype != null) ? mimetype : "application/octet-stream");
      extCtx.setResponseContentLength((int) f.length());
      extCtx.setResponseHeader("Content-Disposition",
         "attachment; filename=\"" + displayName + "\"");

      // Stream to the requester.
      byte[] bbuf = new byte[1024];
      DataInputStream in = new DataInputStream(new FileInputStream(f));

      while ((in != null) && ((length = in.read(bbuf)) != -1)) {
         os.write(bbuf, 0, length);
      }  

      in.close();
   }
}

That's all there is to it!

You can either link to the download page (/download.jsf), or use a HTML meta tag to redirect to it on a splash page.

The previous answer will submit the form and perhaps change the navigation.

Use <rich:jsFunction action="#{bean.action}" name="loadFunction" /> and then window.onload = loadFunction;

You can send only one response per request. You cannot send two responses (the page itself and the download file) per request. Best what you can do is to use Javascript to submit a (hidden) form after page load.

window.onload = function() {
    document.formname.submit();
}

Use events

<ui:composition 
            xmlns="http://www.w3.org/1999/xhtml"
            xmlns:ui="http://java.sun.com/jsf/facelets"
            xmlns:f="http://xmlns.jcp.org/jsf/core"
>
   <f:event type="preRenderView" listener="#{beanName.method}"/>
   ...    
</ui:composition>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!