damian
damian

Reputation: 4044

How to flush buffer early in JSF 2.0?

I'm using JSF 2.0 and I want to flush the buffer early (between head and response) as it is one of the best practices to improve performance. In this article BalusC shows how to do in in a JSP page (<% response.getWriter().flush(); %>), but I'm using xhtml pages. Does anyone know how to do it?

Thanks!
Damian

Upvotes: 1

Views: 2023

Answers (2)

Omirp
Omirp

Reputation: 52

If using myFaces, there is a context param you can set in your web.xml like below:

<context-param>
    <param-name>org.apache.myfaces.EARLY_FLUSH_ENABLED</param-name>
    <param-value>true</param-value>
</context-param>  

Upvotes: 1

BalusC
BalusC

Reputation: 1109172

If you're using <h:head> in JSF2, then you can in theory do this by explicitly flushing the underlying servlet output stream in the encodeEnd() method of the Renderer associated with the component.

There are basically two ways to implement a custom renderer. If you want to be implementation independent, then you have write the entire Renderer yourself which is a piece of work (although for a simple HTML <head> element this is not that hard). You can also choose to be implementation specific so that you end up with a simpler custom Renderer implementation. Assuming that you're using Mojarra, then you just have to extend the com.sun.faces.renderkit.html_basic.HeadRenderer.

E.g.

package com.example;

import java.io.IOException;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import com.sun.faces.renderkit.html_basic.HeadRenderer;

public class FlushedHeadRenderer extends HeadRenderer {

    @Override
    public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
        super.encodeEnd(context, component);
        context.getExternalContext().getResponseOutputWriter().flush(); // Forces flush.
    }

}

which you then register as follows in faces-config.xml:

<render-kit>
    <renderer>
        <component-family>javax.faces.Output</component-family>
        <renderer-type>javax.faces.Head</renderer-type>
        <renderer-class>com.example.FlushedHeadRenderer</renderer-class>
    </renderer>
</render-kit>

However, this approach has caveats. JSF does not have the opportunity anymore to create a session whenever necessary, or to handle any exception as error page whenever an exception is been thrown in midst of rendering the view. I would not recommend this approach for JSF.

Upvotes: 3

Related Questions