Schlagwörter: Richfaces Kommentarverlauf ein-/ausschalten | Tastaturkürzel

  • Andreas Höhmann 14:43 am Monday, 31. March 2008 Permalink |
    Tags: , , File Download, , MyFaces, Richfaces   

    JSF, Ajax and file download 

    Today I show you a example which combines Ajax (Richfaces) and a „normal“ download in a JSF application.

    Here is the bean with the download-code:

    import javax.faces.context.FacesContext;
    import javax.faces.event.ActionEvent;
    import javax.servlet.http.HttpServletResponse;
    public class DownloadBean {
      // actionListener="#{bean.execute}"
      public void execute (ActionEvent event) {
      // action="#{}"
      public String download() {
        final FacesContext facesContext = FacesContext.getCurrentInstance();
        // XXX create temp. filecontent ... resultFile
        writeOutContent(getServletResponse(), new File(this.resultFile), "file.xml");
        // dont use jsf-navigation-rules
        return null;
      void writeOutContent(final HttpServletResponse res, final File content, final String theFilename) {
        if (content == null)
        try {
          res.setHeader("Pragma", "no-cache");
          res.setDateHeader("Expires", 0);
          res.setHeader("Content-disposition", "attachment; filename=" + theFilename);
          fastChannelCopy(Channels.newChannel(new FileInputStream(content)), Channels.newChannel(res.getOutputStream()));
        } catch (final IOException e) {
          // TODO produce a error message 🙂
      void fastChannelCopy(final ReadableByteChannel src, final WritableByteChannel dest) throws IOException {
        final ByteBuffer buffer = ByteBuffer.allocateDirect(16 * 1024);
        while ( != -1) {
        while (buffer.hasRemaining()){

    Now the facelets snipplets: Not Working – Javascript Error 😦

     <h:commandLink actionListener="#{command.execute}" value="Download"/>
     <h:commandLink action="#{}" value="Download"/>

    Not Working – Download is shown in the current page – the ajax page will replaced with the download-content 😦

      <a4j:commandLink actionListener="#{command.execute}" value="Download"/>
      <a4j:commandLink action="#{}" value="Download"/>

    Working 🙂

     <a4j:htmlCommandLink actionListener="#{command.execute}" value="Download"/>
     <a4j:htmlCommandLink action="#{}" value="Download"/>
     <a4j:htmlCommandLink actionListener="#{command.execute}" value="Download"/>
     <a4j:htmlCommandLink action="#{}" value="Download"/>

    The a4j:htmlCommandLink was made for this szenario.

    Notice: the fast channel copy routine was introduced by waffel.

    • walthersoft 13:51 am Freitag, 11. Juli 2008 Permalink | Zum Antworten anmelden

      Nice, was looking for something like this. However, it doesn’t compile, where do you get ‚getServletResponse()‘ in your download() method from ?

    • Andreas Höhmann 7:48 am Donnerstag, 31. Juli 2008 Permalink | Zum Antworten anmelden

      Its a private method wich return the current HttpServletResponse, i haven’t posted because the code is very easy

    • Dummal 15:38 am Mittwoch, 23. Dezember 2009 Permalink | Zum Antworten anmelden

      You saved my day… man!

      thanx a bunchh!

    • ajayjiit 13:42 am Donnerstag, 8. Juli 2010 Permalink | Zum Antworten anmelden

      Hi can you list down the which packages classes ti be imported and zars required.
      iam not able to run it

  • Andreas Höhmann 11:09 am Friday, 7. March 2008 Permalink |
    Tags: a4j, Apache, , Reverse Proxy, Richfaces, View Handler   

    JSF behind reverse proxy 

    The problem „try to run a jsf application behind a reverse proxy“ it will not work if you change the context-path.

    Imagine a local deployed jsf application „hello-world.war“. You can start browsing at http://localhost:8080/hello-word/. The browser handles the absolute paths for css and javascript-libs correctly and all forms will work. Remeber that all resource-urls converted to a „contex-absolut-url“ by the jsf-framework.

    If you open http://localhost:8080/hello-world/index.jsf the the client html will contains resources like this:

    <link rel=’stylesheet‘ type=‚text/css‘
    <script type=‚text/javascript‘ src=‚/hello-world/a4j_3_1_3.GAorg.ajax4jsf.javascript.PrototypeScript.jsf‘>
    <form id=„j_id14“ name=„j_id14“ method=„post“ action=„/hello-world/index.jsf“>

    (Note: I use richfaces 3.1.4 in the example)

    The browser will append each absolute url (starting with ‚/‘) to the host to make the request. And here is the problem if you want to use this jsf-application behind a reverse proxy. Then all absolute URLs pointing to a wrong resource and nothing will work. To try this you can install a local apache web server the following to the httpd.conf:

    Listen 9090
    ProxyRequests On
    ProxyPreserveHost On
    ProxyVia full
    ProxyPass /external-path/hello-world http://localhost:8080/hello-world/

    (This will start the apache at localhost:9090 to avoid port-conflicts)

    If you open http://localhost:9090/external-path/hello-world/index.jsf the the client html contains the same absolute urls and the browser try to load these resource from the „wrong server“: http://localhost:9090/hello-world/. If you imagine a real world szenario then the reverse proxy will use a „real world domain“ and the urls looks like this

    So whats the solution for this? I try my own ViewHandler to convert absolute to relative urls. Two things must be done:

    1. Implement the ViewHandler

    2. Register the ViewHandler

    First the code … we extend javax.faces.application.ViewHandler and overwrite the two methods getActionURL and getResourceURL.

    package de.ahoehma.jsf;
    public class ReverseProxyViewHandler extends ViewHandler {
     public String getActionURL(final FacesContext context, final String viewId) {
      return getRelativeURL(context, this.defaultHandler.getActionURL(context, viewId));
     public String getResourceURL(final FacesContext context, final String path) {
      return getRelativeURL(context, this.defaultHandler.getResourceURL(context, path));
      * Transform the given URL to a relative URL <b>in the context of the current
      * faces request</b>. If the given URL is not absolute do nothing and return
      * the given url. The returned relative URL is "equal" to the original url but
      * will not start with a '/'. So the browser can request the "same" resource
      * but in a relative way and this is important behind reverse proxies!
      * @param context
      * @param theURL
      * @return
     private String getRelativeURL(final FacesContext context, final String theURL) {
      final HttpServletRequest request = ((HttpServletRequest) context.getExternalContext().getRequest());
      String result = theURL;
      if (theURL.startsWith("/")) {
       int subpath = StringUtils.countMatches(getPath(request), "/") - 1;
       String pathPrefix = "";
       if (subpath > 0) {
        while (subpath > 0) {
         pathPrefix += "/..";
        pathPrefix = StringUtils.removeStart(pathPrefix, "/");
       result = pathPrefix + result;
      return result;
      * Get the url-path from the given request.
      * @param request
      * @return clean path
     private String getPath(final HttpServletRequest request) {
      try {
       // TODO handle more than two '/'
       return StringUtils.replace(new URI(request.getRequestURI()).getPath(), "//", "/");
      } catch (final URISyntaxException e) {
      // XXX URISyntaxException ignored
      return StringUtils.EMPTY;

    The absolute2relative-algorithm prepends for each „/“ in the current request-url a „../“ to the resource/action-url … thats all 😀

    And last register the view-handler. If you use A4J you have to add this to your web.xml:


    That’s all 😀

    Now if you open http://localhost:9090/external-path/hello-world/index.jsf the client html contains only relative urls:

    <link rel=’stylesheet‘ type=‚text/css‘
    <script type=‚text/javascript‘ src=‚../hello-world/a4j_3_1_3.GAorg.ajax4jsf.javascript.PrototypeScript.jsf‘>
    <form id=„j_id14“ name=„j_id14“ method=„post“ action=„../hello-world/index.jsf“>

  • Andreas Höhmann 19:59 am Thursday, 17. January 2008 Permalink |
    Tags: , , File Upload, , Richfaces,   

    Fileupload mit Richfaces 

    This article shows the usage of a tomahawk-fileupload with richfaces and facelets. The result is a upload-formular where the upload-button is disabled until the user select a file. All this can be done without any line self hacked javascript-code 🙂

    The upload-button depends on a bean-property ‚uploadedFilename‘ which is sync via AJAX.

    So it is possible to enabled the upload-button before the file is really uploaded to the server.
    We have a jsf-bean:

    public class FileUploadBean  {
      private UploadedFile uploadedFile;
      private String uploadedFilename;
      // ... setter and getter ...
      public void uploadFile(final ActionEvent event) {
        if (null != this.uploadedFile) {
          LOG.debug("file-size '"+this.uploadedFile.getSize()+"'");

    and the facelets-page:

    <c:set var="controlId" value="controls" />
      <a4j:jsFunction name="updateFilename" reRender="#{controlId}">
       <a4j:actionparam name="filename" assignTo="#{FileUploadBean.uploadedFilename}" />
    <h:form enctype="multipart/form-data">
     <t:inputFileUpload id="fileupload"
     <h:panelGroup id="#{controlId}">
         <c:when test="#{!empty FileUploadBean.uploadedFilename}">
           <!-- User has selected a File - enable Upload-Control -->
           <h:commandLink value="Upload enabled ..."
           <!-- User doenst have selected a File - DISABLE Upload-Control -->
           <h:outputText value="Upload disabled"/>
Neuen Beitrag erstellen
nächster Beitrag/nächster Kommentar
vorheriger Beitrag/vorheriger Kommentar
zeige/verstecke Kommentare
Zum Anfang gehen
zum Login
Zeige/Verberge Hilfe
Shift + ESC