I would like to generate a dynamic XML file, after performing a button action method, in JSF 2 and Primefaces.
- If I enable ajax on that button, the output stream is not downloaded to the client
- If I desable ajax, the output stream is downloaded sucessfully, but validation doesn't perform as expected
The action method looks like this:
public void someAction() {
FacesContext context = FacesContext.getCurrentInstance();
ExternalContext ec = context.getExternalContext();
try {
Object someResult = manager.doSomeBusinessLogic();
String contentType = "application/some-type;charset=utf-8";
ec.responseReset();
ec.setResponseContentType(contentType);
ec.setResponseHeader("Content-Disposition", "attachment; filename=\"test.x\"");
OutputStream outputStream = ec.getResponseOutputStream();
writeDataToStream(outputStream, someResult);
} catch (... ex) {
log.error("error", ex);
} finally {
context.responseComplete();
}
}
Is there any way to do this having Ajax enabled and having the file downloaded at the end of the request?
Note: I have also tried to use a PhaseListener to intercept the execution, but I don't know how to pass parameters to the request so that the afterPhase
is able to process parameters accordingly - and I'd rather not do some redirect in order to enter the PhaseListener. Any ideas?
Edit: I'm using Omnifaces 1.6.3 and Primefaces 5.1.
Here is the xhtml:
<o:form>
<h:inputText id="field" value="#{bean.someField}" />
<p:commandButton value="Ajax submit button" action="#{bean.someAction}" />
<f:phaseListener type="com.company.package.SomePhaseListener"/>
</o:form>
Here is my give-it-a-go at the phase listener implementation; the only limitation is adding the someParam
parameter to the HttpServletRequest
on the action method.
public class SomePhaseListener implements PhaseListener {
@Override
public PhaseId getPhaseId() { return PhaseId.RENDER_RESPONSE; }
@Override
public void beforePhase(PhaseEvent event) { ... }
@Override
public void afterPhase(PhaseEvent event) {
FacesContext context = event.getFacesContext();
HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
String someResult = request.getParameter("someParam");
if(someResult != null) {
try {
ExternalContext ec = context.getExternalContext();
ec.responseReset();
ec.setResponseContentType(contentType);
ec.setResponseHeader("Content-Disposition", "attachment; filename=\"test.x\"");
OutputStream outputStream = response.getOutputStream();
writeDataToStream(outputStream, someResult);
} catch (... ex) {
log.error(null, ex);
} finally {
context.responseComplete();
}
}
}
}