user489041
user489041

Reputation: 28294

Redirect from ActionListener in jSF

Im used JSF and PrimeFaces. I have an ActionListener that fires when someone clicks on a MenuItem:

@Override
public void processAction(ActionEvent event) throws AbortProcessingException
{
    Resource resouce = getResources().get(0);
    try
    {
        ResourceDelegate delegate = new ResourceDelegate(resouce, configDao);
        JSFUtils.writeToOutputStream(Mime.getMimeTypeForFileType(FileUtilities.getExtension(resouce.getName())), delegate.getData());
    }
    catch(Exception e)
    {
        logger.log(Level.SEVERE, "Cant show resource",e);
    }

}

In that menu item, I write the data of an image to the request stream using the following code:

/**
 * Writes binary data to the response for the browser to display
 * @param contentType
 * @param data
 * @throws IOException 
 */
public static void writeToOutputStream(String contentType, byte[] data) throws IOException
{
    FacesContext context = FacesContext.getCurrentInstance();
    HttpServletResponse hsr = getHttpServletResponse();
    hsr.setContentType(contentType);
    OutputStream stream = hsr.getOutputStream();
    stream.write(data);
    //Tell JSF to skip the remaining phases of the lifecycle
    context.responseComplete();
}

When the ActionListener is done, I expect that the image would be displayed, however, this is not the case. Nothing happens. Is there something else I need to do to get the image to display correctly?

Upvotes: 0

Views: 2705

Answers (1)

BalusC
BalusC

Reputation: 1108632

That can happen if the request is been fired by ajax, which is by default the case in almost all PrimeFaces action components. In case of JSF/PrimeFaces, ajax requests are supposed to return a special XML response which contains among others information about which parts of the HTML DOM are to be updated and how.

You're here however sending a "file download" as ajax response. This can't be interpreted as such by PrimeFaces' ajax engine. Also, JavaScript has due to security reasons no facilities to force a Save As dialogue. It should really be requested by a synchronous request.

In case of the PrimeFaces <p:menuitem>, you'd need to add the ajax="false" attribute to turn off the ajax nature and let it fire a synchronous request instead.

<p:menuitem ... ajax="false" />

(same attribute is also available on all other action components of PrimeFaces such as <p:commandButton>)

That "nothing happens" is actually not true. You'd have seen the concrete HTTP response in the "Network" section of webbrowser's builtin webdeveloper's toolset (press F12 in Chrome/IE9/Firebug). You should probably even have a JavaScript error in the JavaScript console about an uninterpretable ajax response.

See also:

Upvotes: 4

Related Questions