Навигация по страницам / фаза ответа при отображении игнорируется, если ответ содержит файл - PullRequest
1 голос
/ 10 декабря 2010

JSF / Seam.У меня есть страница, которая принимает некоторые параметры, предоставленные пользователем через форму, а затем (когда пользователь нажимает кнопку на странице) сервер генерирует файл и отправляет его в ответ так, что пользователю предлагается сохранитькак диалог.

Вот сценарий, с которым у меня возникли проблемы:

  1. Если пользователь сначала вводит неверный ввод и затем нажимает кнопку, Seam обрабатывает запрос, но останавливаетсяна этапе проверки процесса.Затем на моей странице отображается сообщение об ошибке проверки.
  2. Далее, если пользователь затем вводит правильный ввод и нажимает кнопку, Seam вызывает мой обработчик действий, файл генерируется и отправляется пользователю в ответ - , но сообщение об ошибке проверки по-прежнему отображается!

Изначально я попытался взломать некоторые из них, чтобы вызвать повторную визуализацию тега <h:messages/>, но ничего не было удовлетворительным. Теперь я подозреваю, что основная причина в том, что Seam не входит в фазу ответа на запрос, когда я помещаю файл в ответ.

Вот моя кнопка:

<h:commandButton value="#{messages.Reports_RunReportPDF}"
                 action="#{bean.generateReportPdf}"/>

А вот мой обработчик действий:

public String generateReportPdf() throws IOException {
  FacesContext facesContext = FacesContext.getCurrentInstance();
  HttpServletResponse response = (HttpServletResponse)facesContext.getExternalContext().getResponse();

  ServletOutputStream servletOutputStream = response.getOutputStream();

  // add this header to make browser prompt user with a save-as dialog
  response.addHeader("Content-Disposition",
                     "attachment;filename=" + reportName + ".pdf");
  response.setContentType(exportType.contentType());

  try {
    HashMap<String, Object> parameters = getReportParameters();
    ReportContent content = createReport(parameters);

    servletOutputStream.write(content.getContents());
    servletOutputStream.flush();
    servletOutputStream.close();
  } catch (ReportingException e) {
    e.printStackTrace();
    return "fail";
  }

  return "success";
}

Если я закомментирую код, который добавляет файл (и просто вернусь "success", страница будет следовать правилам навигации, которые я настроил правильно. Но с файломстраница остается такой же, какой она была до нажатия кнопки.

Итак, как я могу вернуть файл в ответе и вызвать повторную визуализацию тега <h:messages/>?

Ответы [ 2 ]

0 голосов
/ 10 декабря 2010

Итак, как я могу вернуть файл в ответе и вызвать повторную визуализацию тега?

Это невозможно с одним HTTP-запросом. Вы можете вернуть только один ответ на запрос. Это не ограничение JSF, это ограничение HTTP.

Вы можете использовать JavaScript для запуска двух HTTP-запросов одним щелчком мыши, но в вашем конкретном случае это не сработает, поскольку запрос JSF для сообщения зависит от результата запроса на PDF скачать. Я не вижу других способов, кроме как позволить сервлету установить свойство управляемой области сеанса, которая представляет состояние экспорта в PDF, и ввести опрос ajax, который запрашивает это свойство через определенные промежутки времени и останавливается, когда он больше не равен нулю.

0 голосов
/ 10 декабря 2010

Добавьте это к вашему методу после написания

//Skip the rest of JSF phases
FacesContext.getCurrentInstance().responseComplete();

Возможно, вы также захотите добавить закрытие в блок finally, чтобы обеспечить правильное закрытие потока в случае возникновения исключения. Или добавьте аннотацию @ Cleanup от Lombok, и она сделает это автоматически

Обновление

Если вы находитесь в длительной беседе, вы можете завершить беседу до перенаправления, поэтому сообщение проверки будет удалено.

@End(beforeRedirect=true)

...