Сохранение параметров строки запроса GET при отправке формы JSF

У меня есть 3 страницы:

  • main.xhtml
  • agreement.xhtml
  • generated.xhtml

agreement.xhtml для корректной загрузки нужны два параметра: serviceId а также site, Итак, нормальный URL выглядит так: /app/agreement.xhtml?site=US&serviceId=AABBCC,

У меня есть эта кнопка agreement.xhtml

<h:form>
   <h:commandButton value="Generate License File" action="#{agreement.generateMethod}" />   
</h:form>

@RequestScoped боб #{agreement} имеет этот метод:

public String generateMethod(){
    .......
    return "generated";
}

Мне нужно, чтобы по клику generateMethod() метод выполняется, и после того, как это сделано, пользователь перенаправляется на generated.xhtml стр. Что происходит, так это то, что по щелчку браузер страницы отправляет пользователя /app/agreement.xhtml и, поскольку он не отправляет параметры site а также serviceIdсбой.

Я пытался сделать generateMethod() вернуть "generated?faces-redirect=true", но все равно ничего. Есть идеи?

2 ответа

Решение

Ваша конкретная проблема вызвана тем, что JSF <h:form> отправляет по умолчанию текущий URL-адрес запроса без какой-либо строки запроса. Посмотрите внимательнее на сгенерированный вывод HTML, вы увидите

<form action="/app/agreement.xhtml" ...>

Таким образом, вам явно необходимо включить эти параметры запроса самостоятельно. Есть несколько способов решить эту проблему. Если вы не отправляете перенаправление, вы можете просто добавить их в качестве скрытых входных данных в форму JSF.

<h:form>
    <input type="hidden" name="site" value="#{param.site}" />
    <input type="hidden" name="site" value="#{param.serviceId}" />
    ...
</h:form>

Только эти параметры не будут отображаться в URL в адресной строке браузера. Это не проблема, если вы используете только ajax на той же странице. <h:inputHidden> кстати, не подходит, так как он потеряет значение, если в форме произойдет ошибка преобразования или проверки.

Чтобы они снова появлялись в URL, вам нужно <f:viewParam> а также includeViewParams, Чтобы получить includeViewParams чтобы работать, вы должны объявить следующее на исходной странице agreement.xhtml...

<f:metadata>
    <f:viewParam name="site" value="#{agreement.site}" />
    <f:viewParam name="serviceId" value="#{agreement.serviceId}" />
</f:metadata>

...и целевая страница generated.xhtml:

<f:metadata>
    <f:viewParam name="site" value="#{generated.site}" />
    <f:viewParam name="serviceId" value="#{generated.serviceId}" />
</f:metadata>

Теперь вы можете отправить перенаправление, включая параметры просмотра, следующим образом:

public String generateMethod() {
    // ...

    return "generated?faces-redirect=true&includeViewParams=true";
}

Обратите внимание, что бин должен быть@ViewScopedчтобы сохранить эти параметры в действии между открытием страницы с формой и отправкой формы, также на ошибки проверки. В противном случае, придерживаясь@RequestScopedбоб, вы должны сохранить их как <f:param> в компонентах команды:

<h:commandButton ...>
    <f:param name="site" value="#{generated.site}" />
    <f:param name="serviceId" value="#{generated.serviceId}" />
</h:commandButton>

Там нет никакого способа установить их для<f:ajax>внутри входных компонентов ваш компонент должен быть действительно@ViewScoped,


В качестве альтернативы, если вы уже используете служебную библиотеку JSF OmniFaces, то вы также можете просто заменить <h:form>от<o:form> следующим образом (см. также пример витрины):

<o:form includeRequestParams="true">

Это в основном все. Это создаст<form action>с текущей строкой запроса.

<form action="/app/agreement.xhtml?site=US&serviceId=AABBCC" ...>

Эти параметры запроса затем просто доступны в карте параметров запроса формы отправки. Вам не нужны дополнительные метаданные /viewparams, и вам также не нужно отправлять перенаправление, и ваш бин может быть сохранен@RequestScoped, если необходимо.

public String generateMethod() {
    // ...

    return "generated";
}

Или, если вы используете библиотеку "симпатичных URL", такую ​​как PrettyFaces или FacesViews, или, возможно, что-то доморощенное и намереваетесь отправить по тому же URL, что и в адресной строке браузера, вы можете использоватьuseRequestURIвместо.

<o:form useRequestURI="true">

Смотрите также:

Ваш generateMethod должен был бы вернуться

return "generated?site=US&amp;serviceId=AABBCC&amp;faces-redirect=true";

Вы даже можете заменить &amp; с & но избегайте этого в вашем xhtml.

В вашем generated.xhtml вы можете поймать параметры, которые передаются с <f:viewParam> как это

<f:metadata>
    <f:viewParam name="site" value="#{yourBean.site}"/><!--Make sure you have a setter-->
    <f:viewParam name="serviceId" value="#{yourBean.serviceId}"/><!--Make sure you have a setter-
</f:metadata>
<h:head>
Другие вопросы по тегам