На странице JSF у меня есть:
<p:commandButton value="Download" action="#{myMBean.downloadXMLFile}" />
В MBean у меня есть следующее (try/catch ommited):
public void downloadXMLFile() {
String xml = this.getXML();//returns the whole XML but in String format.
HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
response.setContentType("text/xml");
response.setHeader("Content-Disposition", "attachment;filename=file.xml");
ServletOutputStream out = response.getOutputStream();
out.write(xml.getBytes());
out.flush();
}
Но когда я запускаю его, я получаю исключение IllegalStateException:
java.lang.IllegalStateException: setBufferSize() called after first write to Output Stream/Writer
Я также попытался преобразовать XML-строку в документ и преобразовать ее в файл, но получил ту же ошибку. действительно ли это необходимо для того, чтобы работать?
Ошибка возникает из-за попытки отобразить ваш ответ во время фазы рендеринга JSF.
Вы используете исходный объект ответа, полученный через ExternalContext
, и сами пишите ответ. Вы должны указать время выполнения JSF, что ответ завершен, поэтому он не пытается его обработать.
Сохраните ссылку на свой FacesContext
:
FacesContext ctx = FacesContext.getCurrentInstance();
HttpServletResponse response = (HttpServletResponse) ctx.getExternalContext().getResponse();
...
и вызовите responseComplete()
когда вы закончите создание своего ответа:
ctx.responseComplete();
ajax="false"
чтобы отключить любую обработку ajax по умолчанию.
ExternalContext
вы должны вызватьresponseComplete()
в вашем экземпляреFacesContext
чтобы избежать этого.